提交 7e9f3187 编写于 作者: A Alex Dima

Simplify the implementation of ExtensionService

上级 89c8f938
......@@ -7,22 +7,22 @@
import Severity from 'vs/base/common/severity';
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
import { MainProcessExtensionServiceShape } from '../node/extHost.protocol';
import { MainProcessExtensionService } from "vs/workbench/services/extensions/electron-browser/extensionService";
import { ExtensionService } from "vs/workbench/services/extensions/electron-browser/extensionService";
export class MainProcessExtensionServiceAPI extends MainProcessExtensionServiceShape {
private readonly _extensionService: MainProcessExtensionService;
private readonly _extensionService: ExtensionService;
constructor( @IExtensionService extensionService: IExtensionService) {
super();
if (extensionService instanceof MainProcessExtensionService) {
if (extensionService instanceof ExtensionService) {
this._extensionService = extensionService;
}
}
$localShowMessage(severity: Severity, msg: string): void {
this._extensionService._localShowMessage(severity, msg);
this._extensionService._logOrShowMessage(severity, msg);
}
$onExtensionActivated(extensionId: string): void {
}
......
......@@ -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/services/extensions/electron-browser/extensionService";
import { ExtensionService } 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';
......@@ -118,7 +118,7 @@ export class WorkbenchShell {
private configurationService: IConfigurationService;
private contextService: IWorkspaceContextService;
private telemetryService: ITelemetryService;
private extensionService: MainProcessExtensionService;
private extensionService: ExtensionService;
private broadcastService: IBroadcastService;
private timerService: ITimerService;
private themeService: WorkbenchThemeService;
......@@ -321,7 +321,7 @@ export class WorkbenchShell {
serviceCollection.set(IExtensionEnablementService, extensionEnablementService);
disposables.push(extensionEnablementService);
this.extensionService = instantiationService.createInstance(MainProcessExtensionService);
this.extensionService = instantiationService.createInstance(ExtensionService);
serviceCollection.set(IExtensionService, this.extensionService);
serviceCollection.set(IThreadService, this.extensionService);
......
......@@ -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/services/extensions/electron-browser/extensionService";
import { ExtensionService } 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";
......@@ -76,7 +76,7 @@ export class ExtensionHostProcessWorker {
public readonly messagingProtocol = new LazyMessagePassingProtol();
private extensionService: MainProcessExtensionService;
private extensionService: ExtensionService;
constructor(
@IWorkspaceContextService private contextService: IWorkspaceContextService,
......@@ -122,7 +122,7 @@ export class ExtensionHostProcessWorker {
}
}
public start(extensionService: MainProcessExtensionService): void {
public start(extensionService: ExtensionService): void {
this.extensionService = extensionService;
TPromise.join<any>([this.tryListenOnPipe(), this.tryFindDebugPort()]).then(data => {
......
......@@ -8,8 +8,7 @@
import * as nls from 'vs/nls';
import * as Platform from 'vs/base/common/platform';
import pfs = require('vs/base/node/pfs');
import { IExtensionDescription, IMessage } from 'vs/platform/extensions/common/extensions';
import Severity from 'vs/base/common/severity';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { TPromise } from 'vs/base/common/winjs.base';
import { groupBy, values } from 'vs/base/common/collections';
import { join, normalize, extname } from 'path';
......@@ -32,58 +31,23 @@ const nlsConfig: NlsConfiguration = {
pseudo: Platform.locale === 'pseudo'
};
export interface IMessagesCollector {
export interface ILog {
error(source: string, message: string): void;
warn(source: string, message: string): void;
info(source: string, message: string): void;
}
export class MessagesCollector implements IMessagesCollector {
private _messages: IMessage[];
constructor() {
this._messages = [];
}
public getMessages(): IMessage[] {
return this._messages;
}
private _msg(source: string, type: Severity, message: string): void {
this._messages.push({
type: type,
message: message,
source: source,
extensionId: undefined,
extensionPointId: undefined
});
}
public error(source: string, message: string): void {
this._msg(source, Severity.Error, message);
}
public warn(source: string, message: string): void {
this._msg(source, Severity.Warning, message);
}
public info(source: string, message: string): void {
this._msg(source, Severity.Info, message);
}
}
abstract class ExtensionManifestHandler {
protected _ourVersion: string;
protected _collector: IMessagesCollector;
protected _log: ILog;
protected _absoluteFolderPath: string;
protected _isBuiltin: boolean;
protected _absoluteManifestPath: string;
constructor(ourVersion: string, collector: IMessagesCollector, absoluteFolderPath: string, isBuiltin: boolean) {
constructor(ourVersion: string, log: ILog, absoluteFolderPath: string, isBuiltin: boolean) {
this._ourVersion = ourVersion;
this._collector = collector;
this._log = log;
this._absoluteFolderPath = absoluteFolderPath;
this._isBuiltin = isBuiltin;
this._absoluteManifestPath = join(absoluteFolderPath, MANIFEST_FILE);
......@@ -97,7 +61,7 @@ class ExtensionManifestParser extends ExtensionManifestHandler {
try {
return JSON.parse(manifestContents.toString());
} catch (e) {
this._collector.error(this._absoluteFolderPath, nls.localize('jsonParseFail', "Failed to parse {0}: {1}.", this._absoluteManifestPath, getParseErrorMessage(e.message)));
this._log.error(this._absoluteFolderPath, nls.localize('jsonParseFail', "Failed to parse {0}: {1}.", this._absoluteManifestPath, getParseErrorMessage(e.message)));
}
return null;
}, (err) => {
......@@ -105,7 +69,7 @@ class ExtensionManifestParser extends ExtensionManifestHandler {
return null;
}
this._collector.error(this._absoluteFolderPath, nls.localize('fileReadFail', "Cannot read file {0}: {1}.", this._absoluteManifestPath, err.message));
this._log.error(this._absoluteFolderPath, nls.localize('fileReadFail', "Cannot read file {0}: {1}.", this._absoluteManifestPath, err.message));
return null;
});
}
......@@ -132,16 +96,16 @@ class ExtensionManifestNLSReplacer extends ExtensionManifestHandler {
return ExtensionManifestNLSReplacer.resolveOriginalMessageBundle(messageBundle.original, errors).then(originalMessages => {
if (errors.length > 0) {
errors.forEach((error) => {
this._collector.error(this._absoluteFolderPath, nls.localize('jsonsParseFail', "Failed to parse {0} or {1}: {2}.", messageBundle.localized, messageBundle.original, getParseErrorMessage(error.error)));
this._log.error(this._absoluteFolderPath, nls.localize('jsonsParseFail', "Failed to parse {0} or {1}: {2}.", messageBundle.localized, messageBundle.original, getParseErrorMessage(error.error)));
});
return extensionDescription;
}
ExtensionManifestNLSReplacer._replaceNLStrings(extensionDescription, messages, originalMessages, this._collector, this._absoluteFolderPath);
ExtensionManifestNLSReplacer._replaceNLStrings(extensionDescription, messages, originalMessages, this._log, this._absoluteFolderPath);
return extensionDescription;
});
}, (err) => {
this._collector.error(this._absoluteFolderPath, nls.localize('fileReadFail', "Cannot read file {0}: {1}.", messageBundle.localized, err.message));
this._log.error(this._absoluteFolderPath, nls.localize('fileReadFail', "Cannot read file {0}: {1}.", messageBundle.localized, err.message));
return null;
});
});
......@@ -196,7 +160,7 @@ class ExtensionManifestNLSReplacer extends ExtensionManifestHandler {
* This routine makes the following assumptions:
* The root element is an object literal
*/
private static _replaceNLStrings<T>(literal: T, messages: { [key: string]: string; }, originalMessages: { [key: string]: string }, collector: IMessagesCollector, messageScope: string): void {
private static _replaceNLStrings<T>(literal: T, messages: { [key: string]: string; }, originalMessages: { [key: string]: string }, log: ILog, messageScope: string): void {
function processEntry(obj: any, key: string | number, command?: boolean) {
let value = obj[key];
if (Types.isString(value)) {
......@@ -212,7 +176,7 @@ class ExtensionManifestNLSReplacer extends ExtensionManifestHandler {
}
obj[key] = command && (key === 'title' || key === 'category') && originalMessages ? { value: message, original: originalMessages[messageKey] } : message;
} else {
collector.warn(messageScope, nls.localize('missingNLSKey', "Couldn't find message for key {0}.", messageKey));
log.warn(messageScope, nls.localize('missingNLSKey', "Couldn't find message for key {0}.", messageKey));
}
}
} else if (Types.isObject(value)) {
......@@ -258,14 +222,14 @@ class ExtensionManifestValidator extends ExtensionManifestHandler {
let notices: string[] = [];
if (!isValidExtensionDescription(this._ourVersion, this._absoluteFolderPath, extensionDescription, notices)) {
notices.forEach((error) => {
this._collector.error(this._absoluteFolderPath, error);
this._log.error(this._absoluteFolderPath, error);
});
return null;
}
// in this case the notices are warnings
notices.forEach((error) => {
this._collector.warn(this._absoluteFolderPath, error);
this._log.warn(this._absoluteFolderPath, error);
});
// id := `publisher.name`
......@@ -289,26 +253,26 @@ export class ExtensionScanner {
*/
public static scanExtension(
version: string,
collector: IMessagesCollector,
log: ILog,
absoluteFolderPath: string,
isBuiltin: boolean
): TPromise<IExtensionDescription> {
absoluteFolderPath = normalize(absoluteFolderPath);
let parser = new ExtensionManifestParser(version, collector, absoluteFolderPath, isBuiltin);
let parser = new ExtensionManifestParser(version, log, absoluteFolderPath, isBuiltin);
return parser.parse().then((extensionDescription) => {
if (extensionDescription === null) {
return null;
}
let nlsReplacer = new ExtensionManifestNLSReplacer(version, collector, absoluteFolderPath, isBuiltin);
let nlsReplacer = new ExtensionManifestNLSReplacer(version, log, absoluteFolderPath, isBuiltin);
return nlsReplacer.replaceNLS(extensionDescription);
}).then((extensionDescription) => {
if (extensionDescription === null) {
return null;
}
let validator = new ExtensionManifestValidator(version, collector, absoluteFolderPath, isBuiltin);
let validator = new ExtensionManifestValidator(version, log, absoluteFolderPath, isBuiltin);
return validator.validate(extensionDescription);
});
}
......@@ -318,7 +282,7 @@ export class ExtensionScanner {
*/
public static scanExtensions(
version: string,
collector: IMessagesCollector,
log: ILog,
absoluteFolderPath: string,
isBuiltin: boolean
): TPromise<IExtensionDescription[]> {
......@@ -362,10 +326,10 @@ export class ExtensionScanner {
return [...nonGallery, ...latest];
})
.then(folders => TPromise.join(folders.map(f => this.scanExtension(version, collector, join(absoluteFolderPath, f), isBuiltin))))
.then(folders => TPromise.join(folders.map(f => this.scanExtension(version, log, join(absoluteFolderPath, f), isBuiltin))))
.then(extensionDescriptions => extensionDescriptions.filter(item => item !== null))
.then(null, err => {
collector.error(absoluteFolderPath, err);
log.error(absoluteFolderPath, err);
return [];
});
});
......@@ -377,22 +341,22 @@ export class ExtensionScanner {
*/
public static scanOneOrMultipleExtensions(
version: string,
collector: IMessagesCollector,
log: ILog,
absoluteFolderPath: string,
isBuiltin: boolean
): TPromise<IExtensionDescription[]> {
return pfs.fileExists(join(absoluteFolderPath, MANIFEST_FILE)).then((exists) => {
if (exists) {
return this.scanExtension(version, collector, absoluteFolderPath, isBuiltin).then((extensionDescription) => {
return this.scanExtension(version, log, absoluteFolderPath, isBuiltin).then((extensionDescription) => {
if (extensionDescription === null) {
return [];
}
return [extensionDescription];
});
}
return this.scanExtensions(version, collector, absoluteFolderPath, isBuiltin);
return this.scanExtensions(version, log, absoluteFolderPath, isBuiltin);
}, (err) => {
collector.error(absoluteFolderPath, err);
log.error(absoluteFolderPath, err);
return [];
});
}
......
......@@ -15,7 +15,7 @@ import { IMessage, IExtensionDescription, IExtensionsStatus, IExtensionService,
import { IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { areSameExtensions, getGloballyDisabledExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { ExtensionsRegistry, ExtensionPoint, IExtensionPointUser, ExtensionMessageCollector, IExtensionPoint } from 'vs/platform/extensions/common/extensionsRegistry';
import { ExtensionScanner, MessagesCollector } from 'vs/workbench/node/extensionPoints';
import { ExtensionScanner, ILog } from 'vs/workbench/services/extensions/electron-browser/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";
......@@ -29,52 +29,56 @@ import { MainThreadService } from "vs/workbench/services/thread/electron-browser
const SystemExtensionsRoot = path.normalize(path.join(URI.parse(require.toUrl('')).fsPath, '..', 'extensions'));
function messageWithSource(msg: IMessage): string {
return (msg.source ? '[' + msg.source + ']: ' : '') + msg.message;
return messageWithSource2(msg.source, msg.message);
}
function messageWithSource2(source: string, message: string): string {
if (source) {
return `[${source}]: ${message}`;
}
return message;
}
const hasOwnProperty = Object.hasOwnProperty;
const NO_OP_VOID_PROMISE = TPromise.as<void>(void 0);
export abstract class AbstractExtensionService {
public _serviceBrand: any;
/**
* A barrier that is initially closed and then becomes opened permanently.
*/
class Barrier {
private _onReady: TPromise<boolean>;
private _onReadyC: (v: boolean) => void;
private _isReady: boolean;
protected _registry: ExtensionDescriptionRegistry;
private _isOpen: boolean;
private _promise: TPromise<boolean>;
private _completePromise: (v: boolean) => void;
constructor() {
this._isReady = false;
this._onReady = new TPromise<boolean>((c, e, p) => {
this._onReadyC = c;
this._isOpen = false;
this._promise = new TPromise<boolean>((c, e, p) => {
this._completePromise = c;
}, () => {
console.warn('You should really not try to cancel this ready promise!');
});
this._registry = new ExtensionDescriptionRegistry();
}
protected _triggerOnReady(): void {
this._isReady = true;
this._onReadyC(true);
public isOpen(): boolean {
return this._isOpen;
}
public onReady(): TPromise<boolean> {
return this._onReady;
public open(): void {
this._isOpen = true;
this._completePromise(true);
}
public activateByEvent(activationEvent: string): TPromise<void> {
if (this._isReady) {
return this._activateByEvent(activationEvent);
} else {
return this._onReady.then(() => this._activateByEvent(activationEvent));
}
public wait(): TPromise<boolean> {
return this._promise;
}
protected abstract _activateByEvent(activationEvent: string): TPromise<void>;
}
export class MainProcessExtensionService extends AbstractExtensionService implements IThreadService, IExtensionService {
export class ExtensionService implements IThreadService, IExtensionService {
public _serviceBrand: any;
private _registry: ExtensionDescriptionRegistry;
private readonly _barrier: Barrier;
private readonly _isDev: boolean;
private readonly _extensionsStatus: { [id: string]: IExtensionsStatus };
/**
......@@ -92,8 +96,8 @@ export class MainProcessExtensionService extends AbstractExtensionService implem
@IExtensionEnablementService private readonly _extensionEnablementService: IExtensionEnablementService,
@IStorageService private readonly _storageService: IStorageService,
) {
super();
this._registry = null;
this._barrier = new Barrier();
this._isDev = !this._environmentService.isBuilt || this._environmentService.isExtensionDevelopment;
this._extensionsStatus = {};
this._alreadyActivatedEvents = Object.create(null);
......@@ -120,8 +124,13 @@ export class MainProcessExtensionService extends AbstractExtensionService implem
// ---- begin IExtensionService
// public activateByEvent(activationEvent: string): TPromise<void> {
// }
public activateByEvent(activationEvent: string): TPromise<void> {
if (this._barrier.isOpen) {
return this._activateByEvent(activationEvent);
} else {
return this._barrier.wait().then(() => this._activateByEvent(activationEvent));
}
}
protected _activateByEvent(activationEvent: string): TPromise<void> {
if (this._alreadyActivatedEvents[activationEvent]) {
......@@ -132,8 +141,9 @@ export class MainProcessExtensionService extends AbstractExtensionService implem
});
}
// public onReady(): TPromise<boolean> {
// }
public onReady(): TPromise<boolean> {
return this._barrier.wait();
}
public getExtensions(): TPromise<IExtensionDescription[]> {
return this.onReady().then(() => {
......@@ -164,33 +174,15 @@ export class MainProcessExtensionService extends AbstractExtensionService implem
// ---- end IExtensionService
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
});
}
}
// --- impl
private _initialize(): void {
MainProcessExtensionService._scanInstalledExtensions(this._environmentService).done(([installedExtensions, messages]) => {
messages.forEach(entry => this._localShowMessage(entry.type, this._isDev ? (entry.source ? '[' + entry.source + ']: ' : '') + entry.message : entry.message));
const log = new Logger((severity, source, message) => {
this._logOrShowMessage(severity, this._isDev ? messageWithSource2(source, message) : message);
});
ExtensionService._scanInstalledExtensions(this._environmentService, log).then((installedExtensions) => {
const disabledExtensions = [
...getGloballyDisabledExtensions(this._extensionEnablementService, this._storageService, installedExtensions),
...this._extensionEnablementService.getWorkspaceDisabledExtensions()
......@@ -201,16 +193,55 @@ export class MainProcessExtensionService extends AbstractExtensionService implem
disabledCount: disabledExtensions.length
});
this._onExtensionDescriptions(disabledExtensions.length ? installedExtensions.filter(e => disabledExtensions.every(id => !areSameExtensions({ id }, e))) : installedExtensions);
if (disabledExtensions.length === 0) {
return installedExtensions;
}
return installedExtensions.filter(e => disabledExtensions.every(id => !areSameExtensions({ id }, e)));
}).then((extensionDescriptions) => {
this._registry = new ExtensionDescriptionRegistry();
this._registry.registerExtensions(extensionDescriptions);
let availableExtensions = this._registry.getAllExtensionDescriptions();
let extensionPoints = ExtensionsRegistry.getExtensionPoints();
let messageHandler = (msg: IMessage) => this._handleExtensionPointMessage(msg);
for (let i = 0, len = extensionPoints.length; i < len; i++) {
ExtensionService._handleExtensionPoint(extensionPoints[i], availableExtensions, messageHandler);
}
this._barrier.open();
});
}
private static _scanInstalledExtensions(environmentService: IEnvironmentService): TPromise<[IExtensionDescription[], IMessage[]]> {
const collector = new MessagesCollector();
private _handleExtensionPointMessage(msg: IMessage) {
if (!this._extensionsStatus[msg.source]) {
this._extensionsStatus[msg.source] = { messages: [] };
}
this._extensionsStatus[msg.source].messages.push(msg);
if (msg.source === this._environmentService.extensionDevelopmentPath) {
// This message is about the extension currently being developed
this._showMessageToUser(msg.type, messageWithSource(msg));
} else {
this._logMessageInConsole(msg.type, messageWithSource(msg));
}
if (!this._isDev && msg.extensionId) {
const { type, extensionId, extensionPointId, message } = msg;
this._telemetryService.publicLog('extensionsMessage', {
type, extensionId, extensionPointId, message
});
}
}
private static _scanInstalledExtensions(environmentService: IEnvironmentService, log: ILog): TPromise<IExtensionDescription[]> {
const version = pkg.version;
const builtinExtensions = ExtensionScanner.scanExtensions(version, collector, SystemExtensionsRoot, true);
const userExtensions = environmentService.disableExtensions || !environmentService.extensionsPath ? TPromise.as([]) : ExtensionScanner.scanExtensions(version, collector, environmentService.extensionsPath, false);
const developedExtensions = environmentService.disableExtensions || !environmentService.isExtensionDevelopment ? TPromise.as([]) : ExtensionScanner.scanOneOrMultipleExtensions(version, collector, environmentService.extensionDevelopmentPath, false);
const builtinExtensions = ExtensionScanner.scanExtensions(version, log, SystemExtensionsRoot, true);
const userExtensions = environmentService.disableExtensions || !environmentService.extensionsPath ? TPromise.as([]) : ExtensionScanner.scanExtensions(version, log, environmentService.extensionsPath, false);
const developedExtensions = environmentService.disableExtensions || !environmentService.isExtensionDevelopment ? TPromise.as([]) : ExtensionScanner.scanOneOrMultipleExtensions(version, log, environmentService.extensionDevelopmentPath, false);
return TPromise.join([builtinExtensions, userExtensions, developedExtensions]).then<IExtensionDescription[]>((extensionDescriptions: IExtensionDescription[][]) => {
const builtinExtensions = extensionDescriptions[0];
......@@ -223,45 +254,26 @@ export class MainProcessExtensionService extends AbstractExtensionService implem
});
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));
log.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));
log.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));
log.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<IExtensionDescription[]>(null, err => {
collector.error('', err);
log.error('', err);
return [];
}).then<[IExtensionDescription[], IMessage[]]>(extensions => {
const messages = collector.getMessages();
const result: [IExtensionDescription[], IMessage[]] = [extensions, messages];
return result;
});
}
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<T>(extensionPoint: ExtensionPoint<T>, availableExtensions: IExtensionDescription[]): void {
let messageHandler = (msg: IMessage) => this._handleMessage(msg);
private static _handleExtensionPoint<T>(extensionPoint: ExtensionPoint<T>, availableExtensions: IExtensionDescription[], messageHandler: (msg: IMessage) => void): void {
let users: IExtensionPointUser<T>[] = [], usersLen = 0;
for (let i = 0, len = availableExtensions.length; i < len; i++) {
let desc = availableExtensions[i];
......@@ -278,14 +290,16 @@ export class MainProcessExtensionService extends AbstractExtensionService implem
extensionPoint.acceptUsers(users);
}
// -- called by extension host
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)) {
private _showMessageToUser(severity: Severity, msg: string): void {
if (severity === Severity.Error || severity === Severity.Warning) {
this._messageService.show(severity, msg);
} else if (severity === Severity.Error) {
} else {
this._logMessageInConsole(severity, msg);
}
}
private _logMessageInConsole(severity: Severity, msg: string): void {
if (severity === Severity.Error) {
console.error(msg);
} else if (severity === Severity.Warning) {
console.warn(msg);
......@@ -293,4 +307,37 @@ export class MainProcessExtensionService extends AbstractExtensionService implem
console.log(msg);
}
}
// -- called by extension host
public _logOrShowMessage(severity: Severity, msg: string): void {
if (this._isDev) {
this._showMessageToUser(severity, msg);
} else {
this._logMessageInConsole(severity, msg);
}
}
}
export class Logger implements ILog {
private readonly _messageHandler: (severity: Severity, source: string, message: string) => void;
constructor(
messageHandler: (severity: Severity, source: string, message: string) => void
) {
this._messageHandler = messageHandler;
}
public error(source: string, message: string): void {
this._messageHandler(Severity.Error, source, message);
}
public warn(source: string, message: string): void {
this._messageHandler(Severity.Warning, source, message);
}
public info(source: string, message: string): void {
this._messageHandler(Severity.Info, source, message);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册