提交 d03af90a 编写于 作者: I isidor

Properly remove diagnostics.ts

fixes #54486
上级 0f3ed38c
/*---------------------------------------------------------------------------------------------
* 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.<diagnostics name> = 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<string, Function[]>();
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;
}
......@@ -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;
......
......@@ -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 }]))),
......
......@@ -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<TextFileEditorModel> {
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<TextFileEditorModel> {
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<TextFileEditorModel> {
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<TextFileEditorModel> {
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<void>(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<void>(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() + '])');
});
}
......@@ -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<LogLevel>;
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<IResourceDecorationChangeEvent> = Event.None;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册