提交 9fa249ae 编写于 作者: M Matt Bierner

Strict null work on mainThreadSaveParticpants test

上级 311a05dd
......@@ -34,7 +34,7 @@ import { ILogService } from 'vs/platform/log/common/log';
import { IProgressService2, ProgressLocation } from 'vs/platform/progress/common/progress';
import { extHostCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
import { ISaveParticipant, SaveReason, IActiveTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
import { ISaveParticipant, SaveReason, IResolvedTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
import { ExtHostContext, ExtHostDocumentSaveParticipantShape, IExtHostContext } from '../node/extHost.protocol';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
......@@ -51,7 +51,7 @@ class TrimWhitespaceParticipant implements ISaveParticipantParticipant {
// Nothing
}
async participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
if (this.configurationService.getValue('files.trimTrailingWhitespace', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) {
this.doTrimTrailingWhitespace(model.textEditorModel, env.reason === SaveReason.AUTO);
}
......@@ -113,7 +113,7 @@ export class FinalNewLineParticipant implements ISaveParticipantParticipant {
// Nothing
}
async participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
if (this.configurationService.getValue('files.insertFinalNewline', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) {
this.doInsertFinalNewLine(model.textEditorModel);
}
......@@ -151,7 +151,7 @@ export class TrimFinalNewLinesParticipant implements ISaveParticipantParticipant
// Nothing
}
async participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
if (this.configurationService.getValue('files.trimFinalNewlines', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) {
this.doTrimFinalNewLines(model.textEditorModel, env.reason === SaveReason.AUTO);
}
......@@ -222,7 +222,7 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant {
// Nothing
}
async participate(editorModel: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
async participate(editorModel: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
const model = editorModel.textEditorModel;
if (env.reason === SaveReason.AUTO
......@@ -293,7 +293,7 @@ class CodeActionOnSaveParticipant implements ISaveParticipant {
@IConfigurationService private readonly _configurationService: IConfigurationService
) { }
async participate(editorModel: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
async participate(editorModel: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
if (env.reason === SaveReason.AUTO) {
return undefined;
}
......@@ -373,7 +373,7 @@ class ExtHostSaveParticipant implements ISaveParticipantParticipant {
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDocumentSaveParticipant);
}
async participate(editorModel: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
async participate(editorModel: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
if (!shouldSynchronizeModel(editorModel.textEditorModel)) {
// the model never made it to the extension
......@@ -424,7 +424,7 @@ export class SaveParticipant implements ISaveParticipant {
this._saveParticipants.dispose();
}
async participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
return this._progressService.withProgress({ location: ProgressLocation.Window }, progress => {
progress.report({ message: localize('saveParticipants', "Running Save Participants...") });
const promiseFactory = this._saveParticipants.getValue().map(p => () => {
......
......@@ -12,7 +12,7 @@ import { URI } from 'vs/base/common/uri';
import { isUndefinedOrNull } from 'vs/base/common/types';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ITextFileService, IAutoSaveConfiguration, ModelState, ITextFileEditorModel, ISaveOptions, ISaveErrorHandler, ISaveParticipant, StateChange, SaveReason, IRawTextContent, ILoadOptions, LoadReason, IActiveTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
import { ITextFileService, IAutoSaveConfiguration, ModelState, ITextFileEditorModel, ISaveOptions, ISaveErrorHandler, ISaveParticipant, StateChange, SaveReason, IRawTextContent, ILoadOptions, LoadReason, IResolvedTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
import { EncodingMode } from 'vs/workbench/common/editor';
import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel';
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
......@@ -661,7 +661,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
};
this.blockModelContentChange = true;
saveParticipantPromise = TextFileEditorModel.saveParticipant.participate(this as IActiveTextFileEditorModel, { reason: options.reason }).then(onCompleteOrError, onCompleteOrError);
saveParticipantPromise = TextFileEditorModel.saveParticipant.participate(this as IResolvedTextFileEditorModel, { reason: options.reason }).then(onCompleteOrError, onCompleteOrError);
}
// mark the save participant as current pending save operation
......
......@@ -29,7 +29,7 @@ export interface ISaveParticipant {
/**
* Participate in a save of a model. Allows to change the model before it is being saved to disk.
*/
participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise<void>;
participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise<void>;
}
/**
......@@ -255,7 +255,7 @@ export interface ITextFileEditorModel extends ITextEditorModel, IEncodingSupport
isDisposed(): boolean;
}
export interface IActiveTextFileEditorModel extends ITextFileEditorModel {
export interface IResolvedTextFileEditorModel extends ITextFileEditorModel {
readonly textEditorModel: ITextModel;
}
......
......@@ -13,7 +13,7 @@ import { IModelService } from 'vs/editor/common/services/modelService';
import { Range } from 'vs/editor/common/core/range';
import { Selection } from 'vs/editor/common/core/selection';
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
import { ITextFileService, SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
import { ITextFileService, SaveReason, IResolvedTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
import { TextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textFileEditorModelManager';
import { snapshotToString } from 'vs/platform/files/common/files';
......@@ -38,7 +38,7 @@ suite('MainThreadSaveParticipant', function () {
});
test('insert final new line', async function () {
const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/final_new_line.txt'), 'utf8');
const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/final_new_line.txt'), 'utf8') as IResolvedTextFileEditorModel;
await model.load();
const configService = new TestConfigurationService();
......@@ -47,66 +47,66 @@ suite('MainThreadSaveParticipant', function () {
// No new line for empty lines
let lineContent = '';
model.textEditorModel!.setValue(lineContent);
model.textEditorModel.setValue(lineContent);
await participant.participate(model, { reason: SaveReason.EXPLICIT });
assert.equal(snapshotToString(model.createSnapshot()!), lineContent);
// No new line if last line already empty
lineContent = `Hello New Line${model.textEditorModel!.getEOL()}`;
model.textEditorModel!.setValue(lineContent);
lineContent = `Hello New Line${model.textEditorModel.getEOL()}`;
model.textEditorModel.setValue(lineContent);
await participant.participate(model, { reason: SaveReason.EXPLICIT });
assert.equal(snapshotToString(model.createSnapshot()!), lineContent);
// New empty line added (single line)
lineContent = 'Hello New Line';
model.textEditorModel!.setValue(lineContent);
model.textEditorModel.setValue(lineContent);
await participant.participate(model, { reason: SaveReason.EXPLICIT });
assert.equal(snapshotToString(model.createSnapshot()!), `${lineContent}${model.textEditorModel!.getEOL()}`);
assert.equal(snapshotToString(model.createSnapshot()!), `${lineContent}${model.textEditorModel.getEOL()}`);
// New empty line added (multi line)
lineContent = `Hello New Line${model.textEditorModel!.getEOL()}Hello New Line${model.textEditorModel!.getEOL()}Hello New Line`;
model.textEditorModel!.setValue(lineContent);
lineContent = `Hello New Line${model.textEditorModel.getEOL()}Hello New Line${model.textEditorModel.getEOL()}Hello New Line`;
model.textEditorModel.setValue(lineContent);
await participant.participate(model, { reason: SaveReason.EXPLICIT });
assert.equal(snapshotToString(model.createSnapshot()!), `${lineContent}${model.textEditorModel!.getEOL()}`);
assert.equal(snapshotToString(model.createSnapshot()!), `${lineContent}${model.textEditorModel.getEOL()}`);
});
test('trim final new lines', async function () {
const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8');
const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8') as IResolvedTextFileEditorModel;
await model.load();
const configService = new TestConfigurationService();
configService.setUserConfiguration('files', { 'trimFinalNewlines': true });
const participant = new TrimFinalNewLinesParticipant(configService, undefined!);
const textContent = 'Trim New Line';
const eol = `${model.textEditorModel!.getEOL()}`;
const eol = `${model.textEditorModel.getEOL()}`;
// No new line removal if last line is not new line
let lineContent = `${textContent}`;
model.textEditorModel!.setValue(lineContent);
model.textEditorModel.setValue(lineContent);
await participant.participate(model, { reason: SaveReason.EXPLICIT });
assert.equal(snapshotToString(model.createSnapshot()!), lineContent);
// No new line removal if last line is single new line
lineContent = `${textContent}${eol}`;
model.textEditorModel!.setValue(lineContent);
model.textEditorModel.setValue(lineContent);
await participant.participate(model, { reason: SaveReason.EXPLICIT });
assert.equal(snapshotToString(model.createSnapshot()!), lineContent);
// Remove new line (single line with two new lines)
lineContent = `${textContent}${eol}${eol}`;
model.textEditorModel!.setValue(lineContent);
model.textEditorModel.setValue(lineContent);
await participant.participate(model, { reason: SaveReason.EXPLICIT });
assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}`);
// Remove new lines (multiple lines with multiple new lines)
lineContent = `${textContent}${eol}${textContent}${eol}${eol}${eol}`;
model.textEditorModel!.setValue(lineContent);
model.textEditorModel.setValue(lineContent);
await participant.participate(model, { reason: SaveReason.EXPLICIT });
assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}${textContent}${eol}`);
});
test('trim final new lines bug#39750', async function () {
const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8');
const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8') as IResolvedTextFileEditorModel;
await model.load();
const configService = new TestConfigurationService();
......@@ -116,33 +116,33 @@ suite('MainThreadSaveParticipant', function () {
// single line
let lineContent = `${textContent}`;
model.textEditorModel!.setValue(lineContent);
model.textEditorModel.setValue(lineContent);
// apply edits and push to undo stack.
let textEdits = [{ range: new Range(1, 14, 1, 14), text: '.', forceMoveMarkers: false }];
model.textEditorModel!.pushEditOperations([new Selection(1, 14, 1, 14)], textEdits, () => { return [new Selection(1, 15, 1, 15)]; });
model.textEditorModel.pushEditOperations([new Selection(1, 14, 1, 14)], textEdits, () => { return [new Selection(1, 15, 1, 15)]; });
// undo
model.textEditorModel!.undo();
model.textEditorModel.undo();
assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}`);
// trim final new lines should not mess the undo stack
await participant.participate(model, { reason: SaveReason.EXPLICIT });
model.textEditorModel!.redo();
model.textEditorModel.redo();
assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}.`);
});
test('trim final new lines bug#46075', async function () {
const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8');
const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8') as IResolvedTextFileEditorModel;
await model.load();
const configService = new TestConfigurationService();
configService.setUserConfiguration('files', { 'trimFinalNewlines': true });
const participant = new TrimFinalNewLinesParticipant(configService, undefined!);
const textContent = 'Test';
const eol = `${model.textEditorModel!.getEOL()}`;
const eol = `${model.textEditorModel.getEOL()}`;
let content = `${textContent}${eol}${eol}`;
model.textEditorModel!.setValue(content);
model.textEditorModel.setValue(content);
// save many times
for (let i = 0; i < 10; i++) {
......@@ -153,9 +153,9 @@ suite('MainThreadSaveParticipant', function () {
assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}`);
// undo should go back to previous content immediately
model.textEditorModel!.undo();
model.textEditorModel.undo();
assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}${eol}`);
model.textEditorModel!.redo();
model.textEditorModel.redo();
assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}`);
});
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册