diff --git a/src/vs/base/common/diagnostics.ts b/src/vs/base/common/diagnostics.ts deleted file mode 100644 index 7ad7daa18d43b2780bebf9987d0ca616068bc68b..0000000000000000000000000000000000000000 --- a/src/vs/base/common/diagnostics.ts +++ /dev/null @@ -1,88 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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 * as Platform from 'vs/base/common/platform'; - -/** - * To enable diagnostics, open a browser console and type: window.Monaco.Diagnostics. = true. - * Then trigger an action that will write to diagnostics to see all cached output from the past. - */ - -const globals = Platform.globals; -if (!globals.Monaco) { - globals.Monaco = {}; -} -globals.Monaco.Diagnostics = {}; - -const switches = globals.Monaco.Diagnostics; -const map = new Map(); -const data: any[] = []; - -function fifo(array: any[], size: number) { - while (array.length > size) { - array.shift(); - } -} - -export function register(what: string, fn: Function): (...args: any[]) => void { - - let disable = true; // Otherwise we have unreachable code. - if (disable) { - return () => { - // Intentional empty, disable for now because it is leaking memory - }; - } - - // register switch - const flag = switches[what] || false; - switches[what] = flag; - - // register function - const tracers = map.get(what) || []; - tracers.push(fn); - map.set(what, tracers); - - const result = function (...args: any[]) { - - let idx: number; - - if (switches[what] === true) { - // replay back-in-time functions - const allArgs = [arguments]; - idx = data.indexOf(fn); - if (idx !== -1) { - allArgs.unshift.apply(allArgs, data[idx + 1] || []); - data[idx + 1] = []; - } - - const doIt: () => void = function () { - const thisArguments = allArgs.shift(); - fn.apply(fn, thisArguments); - if (allArgs.length > 0) { - setTimeout(doIt, 500); - } - }; - doIt(); - - } else { - // know where to store - idx = data.indexOf(fn); - idx = idx !== -1 ? idx : data.length; - const dataIdx = idx + 1; - - // store arguments - const allargs = data[dataIdx] || []; - allargs.push(arguments); - fifo(allargs, 50); - - // store data - data[idx] = fn; - data[dataIdx] = allargs; - } - }; - - return result; -} diff --git a/src/vs/workbench/parts/files/electron-browser/fileActions.ts b/src/vs/workbench/parts/files/electron-browser/fileActions.ts index 75e5b8c2d8c7962cc494bbef5f20686fda3f90f2..09d50da2f59359c2b3c875b4db10703f92331a4f 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileActions.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileActions.ts @@ -18,7 +18,6 @@ import { posix } from 'path'; import * as errors from 'vs/base/common/errors'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import * as strings from 'vs/base/common/strings'; -import * as diagnostics from 'vs/base/common/diagnostics'; import { Action, IAction } from 'vs/base/common/actions'; import { MessageType, IInputValidator } from 'vs/base/browser/ui/inputbox/inputBox'; import { ITree, IHighlightEvent } from 'vs/base/parts/tree/browser/tree'; @@ -1580,14 +1579,6 @@ class ClipboardContentProvider implements ITextModelContentProvider { } } -// Diagnostics support -let diag: (...args: any[]) => void; -if (!diag) { - diag = diagnostics.register('FileActionsDiagnostics', function (...args: any[]) { - console.log(args[1] + ' - ' + args[0] + ' (time: ' + args[2].getTime() + ' [' + args[2].toUTCString() + '])'); - }); -} - interface IExplorerContext { viewletState: IFileViewletState; stat: ExplorerItem; diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts b/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts index 71af610716f0143c4a6cd220089aec3a88cf1782..bd6ad490b9ed269acaf1f727ae40251387d01246 100644 --- a/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts +++ b/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts @@ -16,7 +16,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { KeyCode, SimpleKeybinding, ChordKeybinding } from 'vs/base/common/keyCodes'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import * as extfs from 'vs/base/node/extfs'; -import { TestTextFileService, TestLifecycleService, TestBackupFileService, TestContextService, TestTextResourceConfigurationService, TestHashService, TestEnvironmentService, TestStorageService, TestEditorGroupsService, TestEditorService } from 'vs/workbench/test/workbenchTestServices'; +import { TestTextFileService, TestLifecycleService, TestBackupFileService, TestContextService, TestTextResourceConfigurationService, TestHashService, TestEnvironmentService, TestStorageService, TestEditorGroupsService, TestEditorService, TestLogService } from 'vs/workbench/test/workbenchTestServices'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; @@ -47,6 +47,7 @@ import { TestConfigurationService } from 'vs/platform/configuration/test/common/ import { IHashService } from 'vs/workbench/services/hash/common/hashService'; import { mkdirp } from 'vs/base/node/pfs'; import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; +import { ILogService } from 'vs/platform/log/common/log'; interface Modifiers { metaKey?: boolean; @@ -82,6 +83,7 @@ suite('KeybindingsEditing', () => { instantiationService.stub(IEditorService, new TestEditorService()); instantiationService.stub(ITelemetryService, NullTelemetryService); instantiationService.stub(IModeService, ModeServiceImpl); + instantiationService.stub(ILogService, new TestLogService()); instantiationService.stub(IModelService, instantiationService.createInstance(ModelServiceImpl)); instantiationService.stub(IFileService, new FileService( new TestContextService(new Workspace(testDir, testDir, toWorkspaceFolders([{ path: testDir }]))), diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 92745915709838c0aa73c8ca4cf633353c0293d5..78fa340fb7d87ded3e8e79a988bc02b88b4bb7f6 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -12,7 +12,6 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { guessMimeTypes } from 'vs/base/common/mime'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import URI from 'vs/base/common/uri'; -import * as diagnostics from 'vs/base/common/diagnostics'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { IMode } from 'vs/editor/common/modes'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; @@ -33,6 +32,7 @@ import { createTextBufferFactory } from 'vs/editor/common/model/textModel'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { isLinux } from 'vs/base/common/platform'; import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { ILogService } from 'vs/platform/log/common/log'; /** * The text file editor model listens to changes to its underlying code editor model and saves these changes through the file service back to the disk. @@ -88,7 +88,8 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil @IBackupFileService private backupFileService: IBackupFileService, @IEnvironmentService private environmentService: IEnvironmentService, @IWorkspaceContextService private contextService: IWorkspaceContextService, - @IHashService private hashService: IHashService + @IHashService private hashService: IHashService, + @ILogService private logService: ILogService ) { super(modelService, modeService); @@ -235,13 +236,13 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } load(options?: ILoadOptions): TPromise { - diag('load() - enter', this.resource, new Date()); + this.logService.trace('load() - enter', this.resource); // It is very important to not reload the model when the model is dirty. // We also only want to reload the model from the disk if no save is pending // to avoid data loss. if (this.dirty || this.saveSequentializer.hasPendingSave()) { - diag('load() - exit - without loading because model is dirty or being saved', this.resource, new Date()); + this.logService.trace('load() - exit - without loading because model is dirty or being saved', this.resource); return TPromise.as(this); } @@ -377,7 +378,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } private doLoadWithContent(content: IRawTextContent, backup?: URI): TPromise { - diag('load() - resolved content', this.resource, new Date()); + this.logService.trace('load() - resolved content', this.resource); // Update our resolved disk stat model this.updateLastResolvedDiskStat({ @@ -409,7 +410,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Join an existing request to create the editor model to avoid race conditions else if (this.createTextEditorModelPromise) { - diag('load() - join existing text editor model promise', this.resource, new Date()); + this.logService.trace('load() - join existing text editor model promise', this.resource); return this.createTextEditorModelPromise; } @@ -419,7 +420,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } private doUpdateTextModel(value: ITextBufferFactory): TPromise { - diag('load() - updated text editor model', this.resource, new Date()); + this.logService.trace('load() - updated text editor model', this.resource); // Ensure we are not tracking a stale state this.setDirty(false); @@ -439,7 +440,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } private doCreateTextModel(resource: URI, value: ITextBufferFactory, backup: URI): TPromise { - diag('load() - created text editor model', this.resource, new Date()); + this.logService.trace('load() - created text editor model', this.resource); this.createTextEditorModelPromise = this.doLoadBackup(backup).then(backupContent => { const hasBackupContent = !!backupContent; @@ -499,11 +500,11 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } private onModelContentChanged(): void { - diag(`onModelContentChanged() - enter`, this.resource, new Date()); + this.logService.trace(`onModelContentChanged() - enter`, this.resource); // In any case increment the version id because it tracks the textual content state of the model at all times this.versionId++; - diag(`onModelContentChanged() - new versionId ${this.versionId}`, this.resource, new Date()); + this.logService.trace(`onModelContentChanged() - new versionId ${this.versionId}`, this.resource); // Ignore if blocking model changes if (this.blockModelContentChange) { @@ -515,7 +516,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Note: we currently only do this check when auto-save is turned off because there you see // a dirty indicator that you want to get rid of when undoing to the saved version. if (!this.autoSaveAfterMilliesEnabled && this.textEditorModel.getAlternativeVersionId() === this.bufferSavedVersionId) { - diag('onModelContentChanged() - model content changed back to last saved version', this.resource, new Date()); + this.logService.trace('onModelContentChanged() - model content changed back to last saved version', this.resource); // Clear flags const wasDirty = this.dirty; @@ -529,7 +530,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil return; } - diag('onModelContentChanged() - model content changed and marked as dirty', this.resource, new Date()); + this.logService.trace('onModelContentChanged() - model content changed and marked as dirty', this.resource); // Mark as dirty this.makeDirty(); @@ -539,7 +540,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil if (!this.inConflictMode) { this.doAutoSave(this.versionId); } else { - diag('makeDirty() - prevented save because we are in conflict resolution mode', this.resource, new Date()); + this.logService.trace('makeDirty() - prevented save because we are in conflict resolution mode', this.resource); } } @@ -560,7 +561,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } private doAutoSave(versionId: number): void { - diag(`doAutoSave() - enter for versionId ${versionId}`, this.resource, new Date()); + this.logService.trace(`doAutoSave() - enter for versionId ${versionId}`, this.resource); // Cancel any currently running auto saves to make this the one that succeeds this.cancelPendingAutoSave(); @@ -589,7 +590,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil return TPromise.wrap(null); } - diag('save() - enter', this.resource, new Date()); + this.logService.trace('save() - enter', this.resource); // Cancel any currently running auto saves to make this the one that succeeds this.cancelPendingAutoSave(); @@ -602,7 +603,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil options.reason = SaveReason.EXPLICIT; } - diag(`doSave(${versionId}) - enter with versionId ' + versionId`, this.resource, new Date()); + this.logService.trace(`doSave(${versionId}) - enter with versionId ' + versionId`, this.resource); // Lookup any running pending save for this versionId and return it if found // @@ -610,7 +611,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // while the save was not yet finished to disk // if (this.saveSequentializer.hasPendingSave(versionId)) { - diag(`doSave(${versionId}) - exit - found a pending save for versionId ${versionId}`, this.resource, new Date()); + this.logService.trace(`doSave(${versionId}) - exit - found a pending save for versionId ${versionId}`, this.resource); return this.saveSequentializer.pendingSave; } @@ -623,7 +624,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Thus we avoid spawning multiple auto saves and only take the latest. // if ((!options.force && !this.dirty) || versionId !== this.versionId) { - diag(`doSave(${versionId}) - exit - because not dirty and/or versionId is different (this.isDirty: ${this.dirty}, this.versionId: ${this.versionId})`, this.resource, new Date()); + this.logService.trace(`doSave(${versionId}) - exit - because not dirty and/or versionId is different (this.isDirty: ${this.dirty}, this.versionId: ${this.versionId})`, this.resource); return TPromise.wrap(null); } @@ -637,7 +638,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // while the first save has not returned yet. // if (this.saveSequentializer.hasPendingSave()) { - diag(`doSave(${versionId}) - exit - because busy saving`, this.resource, new Date()); + this.logService.trace(`doSave(${versionId}) - exit - because busy saving`, this.resource); // Register this as the next upcoming save and return return this.saveSequentializer.setNext(() => this.doSave(this.versionId /* make sure to use latest version id here */, options)); @@ -703,7 +704,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Save to Disk // mark the save operation as currently pending with the versionId (it might have changed from a save participant triggering) - diag(`doSave(${versionId}) - before updateContent()`, this.resource, new Date()); + this.logService.trace(`doSave(${versionId}) - before updateContent()`, this.resource); return this.saveSequentializer.setPending(newVersionId, this.fileService.updateContent(this.lastResolvedDiskStat.resource, this.createSnapshot(), { overwriteReadonly: options.overwriteReadonly, overwriteEncoding: options.overwriteEncoding, @@ -712,7 +713,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil etag: this.lastResolvedDiskStat.etag, writeElevated: options.writeElevated }).then(stat => { - diag(`doSave(${versionId}) - after updateContent()`, this.resource, new Date()); + this.logService.trace(`doSave(${versionId}) - after updateContent()`, this.resource); // Telemetry if (this.isSettingsFile()) { @@ -737,10 +738,10 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Update dirty state unless model has changed meanwhile if (versionId === this.versionId) { - diag(`doSave(${versionId}) - setting dirty to false because versionId did not change`, this.resource, new Date()); + this.logService.trace(`doSave(${versionId}) - setting dirty to false because versionId did not change`, this.resource); this.setDirty(false); } else { - diag(`doSave(${versionId}) - not setting dirty to false because versionId did change meanwhile`, this.resource, new Date()); + this.logService.trace(`doSave(${versionId}) - not setting dirty to false because versionId did change meanwhile`, this.resource); } // Updated resolved stat with updated stat @@ -752,7 +753,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Emit File Saved Event this._onDidStateChange.fire(StateChange.SAVED); }, error => { - diag(`doSave(${versionId}) - exit - resulted in a save error: ${error.toString()}`, this.resource, new Date()); + this.logService.error(`doSave(${versionId}) - exit - resulted in a save error: ${error.toString()}`, this.resource); // Flag as error state in the model this.inErrorMode = true; @@ -1086,11 +1087,3 @@ class DefaultSaveErrorHandler implements ISaveErrorHandler { this.notificationService.error(nls.localize('genericSaveError', "Failed to save '{0}': {1}", path.basename(model.getResource().fsPath), toErrorMessage(error, false))); } } - -// Diagnostics support -let diag: (...args: any[]) => void; -if (!diag) { - diag = diagnostics.register('TextFileEditorModelDiagnostics', function (...args: any[]) { - console.log(args[1] + ' - ' + args[0] + ' (time: ' + args[2].getTime() + ' [' + args[2].toUTCString() + '])'); - }); -} diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index b0049a70ce32c52a34ce924db99150f6cac1c5b1..e1f8c11a8accfd95c4d144394e1f193cd15f14ad 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -74,6 +74,7 @@ import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser'; import { IDecorationRenderOptions } from 'vs/editor/common/editorCommon'; import { EditorGroup } from 'vs/workbench/common/editor/editorGroup'; import { Dimension } from 'vs/base/browser/dom'; +import { ILogService, LogLevel } from 'vs/platform/log/common/log'; export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, void 0); @@ -275,6 +276,7 @@ export function workbenchInstantiationService(): IInstantiationService { instantiationService.stub(IEnvironmentService, TestEnvironmentService); instantiationService.stub(IThemeService, new TestThemeService()); instantiationService.stub(IHashService, new TestHashService()); + instantiationService.stub(ILogService, new TestLogService()); instantiationService.stub(IEditorGroupsService, new TestEditorGroupsService([new TestEditorGroup(0)])); const editorService = new TestEditorService(); instantiationService.stub(IEditorService, editorService); @@ -283,6 +285,19 @@ export function workbenchInstantiationService(): IInstantiationService { return instantiationService; } +export class TestLogService implements ILogService { + _serviceBrand: any; onDidChangeLogLevel: Event; + getLevel(): LogLevel { return LogLevel.Info; } + setLevel(level: LogLevel): void { } + trace(message: string, ...args: any[]): void { } + debug(message: string, ...args: any[]): void { } + info(message: string, ...args: any[]): void { } + warn(message: string, ...args: any[]): void { } + error(message: string | Error, ...args: any[]): void { } + critical(message: string | Error, ...args: any[]): void { } + dispose(): void { } +} + export class TestDecorationsService implements IDecorationsService { _serviceBrand: any; onDidChangeDecorations: Event = Event.None;