From aabeedddea91fbef7615d619a83236e71d4585f8 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Mon, 14 Aug 2017 16:28:05 +0200 Subject: [PATCH] Move extension service code to vs/workbench/services/extensions --- build/lib/i18n.resources.json | 4 + .../mainThreadExtensionService.ts | 249 +---------------- .../electron-browser/extensionHost.ts | 2 +- src/vs/workbench/electron-browser/shell.ts | 2 +- .../electron-browser/extensionService.ts | 250 ++++++++++++++++++ tslint.json | 2 +- 6 files changed, 260 insertions(+), 249 deletions(-) create mode 100644 src/vs/workbench/services/extensions/electron-browser/extensionService.ts diff --git a/build/lib/i18n.resources.json b/build/lib/i18n.resources.json index 40b4073e403..393438d2bfd 100644 --- a/build/lib/i18n.resources.json +++ b/build/lib/i18n.resources.json @@ -154,6 +154,10 @@ "name": "vs/workbench/services/editor", "project": "vscode-workbench" }, + { + "name": "vs/workbench/services/extensions", + "project": "vscode-workbench" + }, { "name": "vs/workbench/services/files", "project": "vscode-workbench" diff --git a/src/vs/workbench/api/electron-browser/mainThreadExtensionService.ts b/src/vs/workbench/api/electron-browser/mainThreadExtensionService.ts index 2b149739079..7fc4fa04952 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadExtensionService.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadExtensionService.ts @@ -5,252 +5,9 @@ 'use strict'; import Severity from 'vs/base/common/severity'; -import { TPromise } from 'vs/base/common/winjs.base'; -import pkg from 'vs/platform/node/package'; -import { localize } from 'vs/nls'; -import * as path from 'path'; -import URI from 'vs/base/common/uri'; -import { AbstractExtensionService, ActivatedExtension } from 'vs/platform/extensions/common/abstractExtensionService'; -import { IMessage, IExtensionDescription, IExtensionsStatus, IExtensionService } from 'vs/platform/extensions/common/extensions'; -import { IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { areSameExtensions, getGloballyDisabledExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; -import { ExtensionsRegistry, ExtensionPoint, IExtensionPointUser, ExtensionMessageCollector } from 'vs/platform/extensions/common/extensionsRegistry'; -import { ExtensionScanner, MessagesCollector } from 'vs/workbench/node/extensionPoints'; -import { IMessageService } from 'vs/platform/message/common/message'; -import { IThreadService, ProxyIdentifier } from 'vs/workbench/services/thread/common/threadService'; -import { ExtHostContext, ExtHostExtensionServiceShape, MainProcessExtensionServiceShape } from '../node/extHost.protocol'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IStorageService } from 'vs/platform/storage/common/storage'; -import { IInstantiationService } from "vs/platform/instantiation/common/instantiation"; -import { ExtensionHostProcessWorker } from "vs/workbench/electron-browser/extensionHost"; -import { MainThreadService } from "vs/workbench/services/thread/electron-browser/threadService"; - -const SystemExtensionsRoot = path.normalize(path.join(URI.parse(require.toUrl('')).fsPath, '..', 'extensions')); - -/** - * Represents a failed extension in the ext host. - */ -class MainProcessFailedExtension extends ActivatedExtension { - constructor() { - super(true); - } -} - -/** - * Represents an extension that was successfully loaded or an - * empty extension in the ext host. - */ -class MainProcessSuccessExtension extends ActivatedExtension { - constructor() { - super(false); - } -} - -function messageWithSource(msg: IMessage): string { - return (msg.source ? '[' + msg.source + ']: ' : '') + msg.message; -} - -const hasOwnProperty = Object.hasOwnProperty; - -export class MainProcessExtensionService extends AbstractExtensionService implements IThreadService { - - private _proxy: ExtHostExtensionServiceShape; - private _isDev: boolean; - private _extensionsStatus: { [id: string]: IExtensionsStatus }; - private _threadService: IThreadService; - - /** - * This class is constructed manually because it is a service, so it doesn't use any ctor injection - */ - constructor( - @IInstantiationService private readonly _instantiationService: IInstantiationService, - @IMessageService private readonly _messageService: IMessageService, - @IEnvironmentService private readonly environmentService: IEnvironmentService, - @ITelemetryService private readonly _telemetryService: ITelemetryService, - @IExtensionEnablementService extensionEnablementService: IExtensionEnablementService, - @IStorageService storageService: IStorageService, - ) { - super(false); - this._isDev = !environmentService.isBuilt || environmentService.isExtensionDevelopment; - - this._extensionsStatus = {}; - - const extensionHostProcessWorker = this._instantiationService.createInstance(ExtensionHostProcessWorker); - this._threadService = this._instantiationService.createInstance(MainThreadService, extensionHostProcessWorker.messagingProtocol); - this._proxy = this._threadService.get(ExtHostContext.ExtHostExtensionService); - extensionHostProcessWorker.start(this); - - this.scanExtensions().done(extensionDescriptions => { - const disabledExtensions = [ - ...getGloballyDisabledExtensions(extensionEnablementService, storageService, extensionDescriptions), - ...extensionEnablementService.getWorkspaceDisabledExtensions() - ]; - - _telemetryService.publicLog('extensionsScanned', { - totalCount: extensionDescriptions.length, - disabledCount: disabledExtensions.length - }); - - this._onExtensionDescriptions(disabledExtensions.length ? extensionDescriptions.filter(e => disabledExtensions.every(id => !areSameExtensions({ id }, e))) : extensionDescriptions); - }); - } - - // ---- begin IThreadService - - public get(identifier: ProxyIdentifier): T { - return this._threadService.get(identifier); - } - - /** - * Register instance. - */ - public set(identifier: ProxyIdentifier, value: T): void { - this._threadService.set(identifier, value); - } - - // ---- end IThreadService - - private _handleMessage(msg: IMessage) { - - if (!this._extensionsStatus[msg.source]) { - this._extensionsStatus[msg.source] = { messages: [] }; - } - this._extensionsStatus[msg.source].messages.push(msg); - - this._localShowMessage( - msg.type, messageWithSource(msg), - this.environmentService.extensionDevelopmentPath === msg.source - ); - - if (!this._isDev && msg.extensionId) { - const { type, extensionId, extensionPointId, message } = msg; - this._telemetryService.publicLog('extensionsMessage', { - type, extensionId, extensionPointId, message - }); - } - } - - public _localShowMessage(severity: Severity, msg: string, useMessageService: boolean = this._isDev): void { - // Only show nasty intrusive messages if doing extension development - // and print all other messages to the console - if (useMessageService && (severity === Severity.Error || severity === Severity.Warning)) { - this._messageService.show(severity, msg); - } else if (severity === Severity.Error) { - console.error(msg); - } else if (severity === Severity.Warning) { - console.warn(msg); - } else { - console.log(msg); - } - } - - // -- overwriting AbstractExtensionService - - public getExtensionsStatus(): { [id: string]: IExtensionsStatus } { - return this._extensionsStatus; - } - - protected _showMessage(severity: Severity, msg: string): void { - this._localShowMessage(severity, msg); - } - - protected _createFailedExtension(): ActivatedExtension { - return new MainProcessFailedExtension(); - } - - protected _actualActivateExtension(extensionDescription: IExtensionDescription): TPromise { - - // redirect extension activation to the extension host - return this._proxy.$activateExtension(extensionDescription).then(_ => { - - // the extension host calls $onExtensionActivated, where we write to `_activatedExtensions` - return this._activatedExtensions[extensionDescription.id]; - }); - } - - // -- called by extension host - - private _onExtensionDescriptions(extensionDescriptions: IExtensionDescription[]): void { - this._registry.registerExtensions(extensionDescriptions); - - let availableExtensions = this._registry.getAllExtensionDescriptions(); - let extensionPoints = ExtensionsRegistry.getExtensionPoints(); - - for (let i = 0, len = extensionPoints.length; i < len; i++) { - this._handleExtensionPoint(extensionPoints[i], availableExtensions); - } - - this._triggerOnReady(); - } - - private _handleExtensionPoint(extensionPoint: ExtensionPoint, availableExtensions: IExtensionDescription[]): void { - let messageHandler = (msg: IMessage) => this._handleMessage(msg); - - let users: IExtensionPointUser[] = [], usersLen = 0; - for (let i = 0, len = availableExtensions.length; i < len; i++) { - let desc = availableExtensions[i]; - - if (desc.contributes && hasOwnProperty.call(desc.contributes, extensionPoint.name)) { - users[usersLen++] = { - description: desc, - value: desc.contributes[extensionPoint.name], - collector: new ExtensionMessageCollector(messageHandler, desc, extensionPoint.name) - }; - } - } - - extensionPoint.acceptUsers(users); - } - - public _onExtensionActivated(extensionId: string): void { - this._activatedExtensions[extensionId] = new MainProcessSuccessExtension(); - } - - public _onExtensionActivationFailed(extensionId: string): void { - this._activatedExtensions[extensionId] = new MainProcessFailedExtension(); - } - - private scanExtensions(): TPromise { - const collector = new MessagesCollector(); - const version = pkg.version; - const builtinExtensions = ExtensionScanner.scanExtensions(version, collector, SystemExtensionsRoot, true); - const userExtensions = this.environmentService.disableExtensions || !this.environmentService.extensionsPath ? TPromise.as([]) : ExtensionScanner.scanExtensions(version, collector, this.environmentService.extensionsPath, false); - const developedExtensions = this.environmentService.disableExtensions || !this.environmentService.isExtensionDevelopment ? TPromise.as([]) : ExtensionScanner.scanOneOrMultipleExtensions(version, collector, this.environmentService.extensionDevelopmentPath, false); - - return TPromise.join([builtinExtensions, userExtensions, developedExtensions]).then((extensionDescriptions: IExtensionDescription[][]) => { - let builtinExtensions = extensionDescriptions[0]; - let userExtensions = extensionDescriptions[1]; - let developedExtensions = extensionDescriptions[2]; - - let result: { [extensionId: string]: IExtensionDescription; } = {}; - builtinExtensions.forEach((builtinExtension) => { - result[builtinExtension.id] = builtinExtension; - }); - userExtensions.forEach((userExtension) => { - if (result.hasOwnProperty(userExtension.id)) { - collector.warn(userExtension.extensionFolderPath, localize('overwritingExtension', "Overwriting extension {0} with {1}.", result[userExtension.id].extensionFolderPath, userExtension.extensionFolderPath)); - } - result[userExtension.id] = userExtension; - }); - developedExtensions.forEach(developedExtension => { - collector.info('', localize('extensionUnderDevelopment', "Loading development extension at {0}", developedExtension.extensionFolderPath)); - if (result.hasOwnProperty(developedExtension.id)) { - collector.warn(developedExtension.extensionFolderPath, localize('overwritingExtension', "Overwriting extension {0} with {1}.", result[developedExtension.id].extensionFolderPath, developedExtension.extensionFolderPath)); - } - result[developedExtension.id] = developedExtension; - }); - - return Object.keys(result).map(name => result[name]); - }).then(null, err => { - collector.error('', err); - return []; - }).then(extensions => { - collector.getMessages().forEach(entry => this._localShowMessage(entry.type, this._isDev ? (entry.source ? '[' + entry.source + ']: ' : '') + entry.message : entry.message)); - return extensions; - }); - } -} +import { IExtensionService } from 'vs/platform/extensions/common/extensions'; +import { MainProcessExtensionServiceShape } from '../node/extHost.protocol'; +import { MainProcessExtensionService } from "vs/workbench/services/extensions/electron-browser/extensionService"; export class MainProcessExtensionServiceAPI extends MainProcessExtensionServiceShape { diff --git a/src/vs/workbench/electron-browser/extensionHost.ts b/src/vs/workbench/electron-browser/extensionHost.ts index fea8c3c48de..b4316cdfa97 100644 --- a/src/vs/workbench/electron-browser/extensionHost.ts +++ b/src/vs/workbench/electron-browser/extensionHost.ts @@ -31,7 +31,7 @@ import { createServer, Server } from 'net'; import Event, { Emitter, debounceEvent, mapEvent, any } from 'vs/base/common/event'; import { fromEventEmitter } from 'vs/base/node/event'; import { IInitData, IWorkspaceData } from 'vs/workbench/api/node/extHost.protocol'; -import { MainProcessExtensionService } from 'vs/workbench/api/electron-browser/mainThreadExtensionService'; +import { MainProcessExtensionService } from "vs/workbench/services/extensions/electron-browser/extensionService"; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { ICrashReporterService } from 'vs/workbench/services/crashReporter/common/crashReporterService'; import { IBroadcastService, IBroadcast } from "vs/platform/broadcast/electron-browser/broadcastService"; diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index 32afce38601..294376c14df 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -49,7 +49,7 @@ import { IntegrityServiceImpl } from 'vs/platform/integrity/node/integrityServic import { IIntegrityService } from 'vs/platform/integrity/common/integrity'; import { EditorWorkerServiceImpl } from 'vs/editor/common/services/editorWorkerServiceImpl'; import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService'; -import { MainProcessExtensionService } from 'vs/workbench/api/electron-browser/mainThreadExtensionService'; +import { MainProcessExtensionService } from "vs/workbench/services/extensions/electron-browser/extensionService"; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts new file mode 100644 index 00000000000..13e4a02c831 --- /dev/null +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -0,0 +1,250 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import Severity from 'vs/base/common/severity'; +import { TPromise } from 'vs/base/common/winjs.base'; +import pkg from 'vs/platform/node/package'; +import { localize } from 'vs/nls'; +import * as path from 'path'; +import URI from 'vs/base/common/uri'; +import { AbstractExtensionService, ActivatedExtension } from 'vs/platform/extensions/common/abstractExtensionService'; +import { IMessage, IExtensionDescription, IExtensionsStatus } from 'vs/platform/extensions/common/extensions'; +import { IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { areSameExtensions, getGloballyDisabledExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; +import { ExtensionsRegistry, ExtensionPoint, IExtensionPointUser, ExtensionMessageCollector } from 'vs/platform/extensions/common/extensionsRegistry'; +import { ExtensionScanner, MessagesCollector } from 'vs/workbench/node/extensionPoints'; +import { IMessageService } from 'vs/platform/message/common/message'; +import { IThreadService, ProxyIdentifier } from 'vs/workbench/services/thread/common/threadService'; +import { ExtHostContext, ExtHostExtensionServiceShape } from "vs/workbench/api/node/extHost.protocol"; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IStorageService } from 'vs/platform/storage/common/storage'; +import { IInstantiationService } from "vs/platform/instantiation/common/instantiation"; +import { ExtensionHostProcessWorker } from "vs/workbench/electron-browser/extensionHost"; +import { MainThreadService } from "vs/workbench/services/thread/electron-browser/threadService"; + +const SystemExtensionsRoot = path.normalize(path.join(URI.parse(require.toUrl('')).fsPath, '..', 'extensions')); + +/** + * Represents a failed extension in the ext host. + */ +class MainProcessFailedExtension extends ActivatedExtension { + constructor() { + super(true); + } +} + +/** + * Represents an extension that was successfully loaded or an + * empty extension in the ext host. + */ +class MainProcessSuccessExtension extends ActivatedExtension { + constructor() { + super(false); + } +} + +function messageWithSource(msg: IMessage): string { + return (msg.source ? '[' + msg.source + ']: ' : '') + msg.message; +} + +const hasOwnProperty = Object.hasOwnProperty; + +export class MainProcessExtensionService extends AbstractExtensionService implements IThreadService { + + private _proxy: ExtHostExtensionServiceShape; + private _isDev: boolean; + private _extensionsStatus: { [id: string]: IExtensionsStatus }; + private _threadService: IThreadService; + + /** + * This class is constructed manually because it is a service, so it doesn't use any ctor injection + */ + constructor( + @IInstantiationService private readonly _instantiationService: IInstantiationService, + @IMessageService private readonly _messageService: IMessageService, + @IEnvironmentService private readonly environmentService: IEnvironmentService, + @ITelemetryService private readonly _telemetryService: ITelemetryService, + @IExtensionEnablementService extensionEnablementService: IExtensionEnablementService, + @IStorageService storageService: IStorageService, + ) { + super(false); + this._isDev = !environmentService.isBuilt || environmentService.isExtensionDevelopment; + + this._extensionsStatus = {}; + + const extensionHostProcessWorker = this._instantiationService.createInstance(ExtensionHostProcessWorker); + this._threadService = this._instantiationService.createInstance(MainThreadService, extensionHostProcessWorker.messagingProtocol); + this._proxy = this._threadService.get(ExtHostContext.ExtHostExtensionService); + extensionHostProcessWorker.start(this); + + this.scanExtensions().done(extensionDescriptions => { + const disabledExtensions = [ + ...getGloballyDisabledExtensions(extensionEnablementService, storageService, extensionDescriptions), + ...extensionEnablementService.getWorkspaceDisabledExtensions() + ]; + + _telemetryService.publicLog('extensionsScanned', { + totalCount: extensionDescriptions.length, + disabledCount: disabledExtensions.length + }); + + this._onExtensionDescriptions(disabledExtensions.length ? extensionDescriptions.filter(e => disabledExtensions.every(id => !areSameExtensions({ id }, e))) : extensionDescriptions); + }); + } + + // ---- begin IThreadService + + public get(identifier: ProxyIdentifier): T { + return this._threadService.get(identifier); + } + + public set(identifier: ProxyIdentifier, value: T): void { + this._threadService.set(identifier, value); + } + + // ---- end IThreadService + + private _handleMessage(msg: IMessage) { + + if (!this._extensionsStatus[msg.source]) { + this._extensionsStatus[msg.source] = { messages: [] }; + } + this._extensionsStatus[msg.source].messages.push(msg); + + this._localShowMessage( + msg.type, messageWithSource(msg), + this.environmentService.extensionDevelopmentPath === msg.source + ); + + if (!this._isDev && msg.extensionId) { + const { type, extensionId, extensionPointId, message } = msg; + this._telemetryService.publicLog('extensionsMessage', { + type, extensionId, extensionPointId, message + }); + } + } + + public _localShowMessage(severity: Severity, msg: string, useMessageService: boolean = this._isDev): void { + // Only show nasty intrusive messages if doing extension development + // and print all other messages to the console + if (useMessageService && (severity === Severity.Error || severity === Severity.Warning)) { + this._messageService.show(severity, msg); + } else if (severity === Severity.Error) { + console.error(msg); + } else if (severity === Severity.Warning) { + console.warn(msg); + } else { + console.log(msg); + } + } + + // -- overwriting AbstractExtensionService + + public getExtensionsStatus(): { [id: string]: IExtensionsStatus } { + return this._extensionsStatus; + } + + protected _showMessage(severity: Severity, msg: string): void { + this._localShowMessage(severity, msg); + } + + protected _createFailedExtension(): ActivatedExtension { + return new MainProcessFailedExtension(); + } + + protected _actualActivateExtension(extensionDescription: IExtensionDescription): TPromise { + + // redirect extension activation to the extension host + return this._proxy.$activateExtension(extensionDescription).then(_ => { + + // the extension host calls $onExtensionActivated, where we write to `_activatedExtensions` + return this._activatedExtensions[extensionDescription.id]; + }); + } + + // -- called by extension host + + private _onExtensionDescriptions(extensionDescriptions: IExtensionDescription[]): void { + this._registry.registerExtensions(extensionDescriptions); + + let availableExtensions = this._registry.getAllExtensionDescriptions(); + let extensionPoints = ExtensionsRegistry.getExtensionPoints(); + + for (let i = 0, len = extensionPoints.length; i < len; i++) { + this._handleExtensionPoint(extensionPoints[i], availableExtensions); + } + + this._triggerOnReady(); + } + + private _handleExtensionPoint(extensionPoint: ExtensionPoint, availableExtensions: IExtensionDescription[]): void { + let messageHandler = (msg: IMessage) => this._handleMessage(msg); + + let users: IExtensionPointUser[] = [], usersLen = 0; + for (let i = 0, len = availableExtensions.length; i < len; i++) { + let desc = availableExtensions[i]; + + if (desc.contributes && hasOwnProperty.call(desc.contributes, extensionPoint.name)) { + users[usersLen++] = { + description: desc, + value: desc.contributes[extensionPoint.name], + collector: new ExtensionMessageCollector(messageHandler, desc, extensionPoint.name) + }; + } + } + + extensionPoint.acceptUsers(users); + } + + public _onExtensionActivated(extensionId: string): void { + this._activatedExtensions[extensionId] = new MainProcessSuccessExtension(); + } + + public _onExtensionActivationFailed(extensionId: string): void { + this._activatedExtensions[extensionId] = new MainProcessFailedExtension(); + } + + private scanExtensions(): TPromise { + const collector = new MessagesCollector(); + const version = pkg.version; + const builtinExtensions = ExtensionScanner.scanExtensions(version, collector, SystemExtensionsRoot, true); + const userExtensions = this.environmentService.disableExtensions || !this.environmentService.extensionsPath ? TPromise.as([]) : ExtensionScanner.scanExtensions(version, collector, this.environmentService.extensionsPath, false); + const developedExtensions = this.environmentService.disableExtensions || !this.environmentService.isExtensionDevelopment ? TPromise.as([]) : ExtensionScanner.scanOneOrMultipleExtensions(version, collector, this.environmentService.extensionDevelopmentPath, false); + + return TPromise.join([builtinExtensions, userExtensions, developedExtensions]).then((extensionDescriptions: IExtensionDescription[][]) => { + let builtinExtensions = extensionDescriptions[0]; + let userExtensions = extensionDescriptions[1]; + let developedExtensions = extensionDescriptions[2]; + + let result: { [extensionId: string]: IExtensionDescription; } = {}; + builtinExtensions.forEach((builtinExtension) => { + result[builtinExtension.id] = builtinExtension; + }); + userExtensions.forEach((userExtension) => { + if (result.hasOwnProperty(userExtension.id)) { + collector.warn(userExtension.extensionFolderPath, localize('overwritingExtension', "Overwriting extension {0} with {1}.", result[userExtension.id].extensionFolderPath, userExtension.extensionFolderPath)); + } + result[userExtension.id] = userExtension; + }); + developedExtensions.forEach(developedExtension => { + collector.info('', localize('extensionUnderDevelopment', "Loading development extension at {0}", developedExtension.extensionFolderPath)); + if (result.hasOwnProperty(developedExtension.id)) { + collector.warn(developedExtension.extensionFolderPath, localize('overwritingExtension', "Overwriting extension {0} with {1}.", result[developedExtension.id].extensionFolderPath, developedExtension.extensionFolderPath)); + } + result[developedExtension.id] = developedExtension; + }); + + return Object.keys(result).map(name => result[name]); + }).then(null, err => { + collector.error('', err); + return []; + }).then(extensions => { + collector.getMessages().forEach(entry => this._localShowMessage(entry.type, this._isDev ? (entry.source ? '[' + entry.source + ']: ' : '') + entry.message : entry.message)); + return extensions; + }); + } +} diff --git a/tslint.json b/tslint.json index 334e74b13c4..6bcc49e7bd9 100644 --- a/tslint.json +++ b/tslint.json @@ -355,7 +355,7 @@ "**/vs/base/**", "**/vs/platform/**", "**/vs/editor/**", - "**/vs/workbench/{common,browser,node,electron-browser}/**", + "**/vs/workbench/{common,browser,node,electron-browser,api}/**", "**/vs/workbench/services/**", "*" // node modules ]