Merge from vscode de81ccf04849309f843db21130c806a5783678f7 (#4738)

This commit is contained in:
Anthony Dresser
2019-03-28 13:06:16 -07:00
committed by GitHub
parent cc2951265e
commit e6785ffe95
77 changed files with 562 additions and 835 deletions

View File

@@ -6,21 +6,23 @@
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import * as extfs from 'vs/base/node/extfs';
import { dirname, join } from 'vs/base/common/path';
import * as resources from 'vs/base/common/resources';
import { ITextModel } from 'vs/editor/common/model';
import { URI } from 'vs/base/common/uri';
import { ThrottledDelayer } from 'vs/base/common/async';
import { IFileService } from 'vs/platform/files/common/files';
import { IModelService } from 'vs/editor/common/services/modelService';
import { IModeService } from 'vs/editor/common/services/modeService';
import { toDisposable, IDisposable } from 'vs/base/common/lifecycle';
import { toDisposable, IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { ILogService } from 'vs/platform/log/common/log';
import { IOutputChannelModel, AbstractFileOutputChannelModel, IOutputChannelModelService, AsbtractOutputChannelModelService } from 'vs/workbench/services/output/common/outputChannelModel';
import { IOutputChannelModel, AbstractFileOutputChannelModel, IOutputChannelModelService, AsbtractOutputChannelModelService, BufferredOutputChannel } from 'vs/workbench/services/output/common/outputChannelModel';
import { OutputAppender } from 'vs/workbench/services/output/node/outputAppender';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IWindowService } from 'vs/platform/windows/common/windows';
import { toLocalISOString } from 'vs/base/common/date';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { Emitter, Event } from 'vs/base/common/event';
let watchingOutputDir = false;
let callbacks: ((eventType: string, fileName?: string) => void)[] = [];
@@ -55,15 +57,13 @@ class OutputChannelBackedByFile extends AbstractFileOutputChannelModel implement
id: string,
modelUri: URI,
mimeType: string,
@IWindowService windowService: IWindowService,
@IEnvironmentService environmentService: IEnvironmentService,
file: URI,
@IFileService fileService: IFileService,
@IModelService modelService: IModelService,
@IModeService modeService: IModeService,
@ILogService logService: ILogService
) {
const outputDir = join(environmentService.logsPath, `output_${windowService.getCurrentWindowId()}_${toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, '')}`);
super(modelUri, mimeType, URI.file(join(outputDir, `${id}.log`)), fileService, modelService, modeService);
super(modelUri, mimeType, file, fileService, modelService, modeService);
this.appendedMessage = '';
this.loadingFromFileInProgress = false;
@@ -159,32 +159,93 @@ class OutputChannelBackedByFile extends AbstractFileOutputChannelModel implement
}
}
class DelegatedOutputChannelModel extends Disposable implements IOutputChannelModel {
private readonly _onDidAppendedContent: Emitter<void> = this._register(new Emitter<void>());
readonly onDidAppendedContent: Event<void> = this._onDidAppendedContent.event;
private readonly _onDispose: Emitter<void> = this._register(new Emitter<void>());
readonly onDispose: Event<void> = this._onDispose.event;
private readonly outputChannelModel: Promise<IOutputChannelModel>;
constructor(
id: string,
modelUri: URI,
mimeType: string,
outputDir: Promise<URI>,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@ILogService private readonly logService: ILogService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
) {
super();
this.outputChannelModel = this.createOutputChannelModel(id, modelUri, mimeType, outputDir);
}
private async createOutputChannelModel(id: string, modelUri: URI, mimeType: string, outputDirPromise: Promise<URI>): Promise<IOutputChannelModel> {
let outputChannelModel: IOutputChannelModel;
try {
const outputDir = await outputDirPromise;
const file = resources.joinPath(outputDir, `${id}.log`);
outputChannelModel = this.instantiationService.createInstance(OutputChannelBackedByFile, id, modelUri, mimeType, file);
} catch (e) {
// Do not crash if spdlog rotating logger cannot be loaded (workaround for https://github.com/Microsoft/vscode/issues/47883)
this.logService.error(e);
/* __GDPR__
"output.channel.creation.error" : {}
*/
this.telemetryService.publicLog('output.channel.creation.error');
outputChannelModel = this.instantiationService.createInstance(BufferredOutputChannel, modelUri, mimeType);
}
this._register(outputChannelModel);
this._register(outputChannelModel.onDidAppendedContent(() => this._onDidAppendedContent.fire()));
this._register(outputChannelModel.onDispose(() => this._onDispose.fire()));
return outputChannelModel;
}
append(output: string): void {
this.outputChannelModel.then(outputChannelModel => outputChannelModel.append(output));
}
update(): void {
this.outputChannelModel.then(outputChannelModel => outputChannelModel.update());
}
loadModel(): Promise<ITextModel> {
return this.outputChannelModel.then(outputChannelModel => outputChannelModel.loadModel());
}
clear(till?: number): void {
this.outputChannelModel.then(outputChannelModel => outputChannelModel.clear(till));
}
}
export class OutputChannelModelService extends AsbtractOutputChannelModelService implements IOutputChannelModelService {
_serviceBrand: any;
constructor(
@IInstantiationService instantiationService: IInstantiationService,
@ILogService private readonly logService: ILogService,
@ITelemetryService private readonly telemetryService: ITelemetryService
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@IWindowService private readonly windowService: IWindowService,
@IFileService private readonly fileService: IFileService
) {
super(instantiationService);
}
createOutputChannelModel(id: string, modelUri: URI, mimeType: string, file?: URI): IOutputChannelModel {
if (!file) {
try {
return this.instantiationService.createInstance(OutputChannelBackedByFile, id, modelUri, mimeType);
} catch (e) {
// Do not crash if spdlog rotating logger cannot be loaded (workaround for https://github.com/Microsoft/vscode/issues/47883)
this.logService.error(e);
/* __GDPR__
"output.channel.creation.error" : {}
*/
this.telemetryService.publicLog('output.channel.creation.error');
}
return file ? super.createOutputChannelModel(id, modelUri, mimeType, file) :
this.instantiationService.createInstance(DelegatedOutputChannelModel, id, modelUri, mimeType, this.outputDir);
}
private _outputDir: Promise<URI> | null;
private get outputDir(): Promise<URI> {
if (!this._outputDir) {
const outputDir = URI.file(join(this.environmentService.logsPath, `output_${this.windowService.getCurrentWindowId()}_${toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, '')}`));
this._outputDir = this.fileService.createFolder(outputDir).then(() => outputDir);
}
return super.createOutputChannelModel(id, modelUri, mimeType, file);
return this._outputDir;
}
}