Dispose `PieceTreeTextBuffer` instances

上级 e114a24d
......@@ -600,12 +600,6 @@ export interface ITextModel {
*/
setValue(newValue: string): void;
/**
* Replace the entire text buffer value contained in this model.
* @internal
*/
setValueFromTextBuffer(newValue: ITextBuffer): void;
/**
* Get the text stored in this model.
* @param eol The end of line character preference. Defaults to `EndOfLinePreference.TextDefined`.
......@@ -1276,7 +1270,7 @@ export interface ITextBufferBuilder {
* @internal
*/
export interface ITextBufferFactory {
create(defaultEOL: DefaultEndOfLine): ITextBuffer;
create(defaultEOL: DefaultEndOfLine): { textBuffer: ITextBuffer; disposable: IDisposable; };
getFirstLineText(lengthLimit: number): string;
}
......
......@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { CharCode } from 'vs/base/common/charCode';
import { IDisposable } from 'vs/base/common/lifecycle';
import * as strings from 'vs/base/common/strings';
import { DefaultEndOfLine, ITextBuffer, ITextBufferBuilder, ITextBufferFactory } from 'vs/editor/common/model';
import { StringBuffer, createLineStarts, createLineStartsFast } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase';
......@@ -38,7 +39,7 @@ export class PieceTreeTextBufferFactory implements ITextBufferFactory {
return '\n';
}
public create(defaultEOL: DefaultEndOfLine): ITextBuffer {
public create(defaultEOL: DefaultEndOfLine): { textBuffer: ITextBuffer; disposable: IDisposable; } {
const eol = this._getEOL(defaultEOL);
let chunks = this._chunks;
......@@ -54,7 +55,8 @@ export class PieceTreeTextBufferFactory implements ITextBufferFactory {
}
}
return new PieceTreeTextBuffer(chunks, this._bom, eol, this._containsRTL, this._containsUnusualLineTerminators, this._isBasicASCII, this._normalizeEOL);
const textBuffer = new PieceTreeTextBuffer(chunks, this._bom, eol, this._containsRTL, this._containsUnusualLineTerminators, this._isBasicASCII, this._normalizeEOL);
return { textBuffer: textBuffer, disposable: textBuffer };
}
public getFirstLineText(lengthLimit: number): string {
......
......@@ -107,7 +107,7 @@ export function createTextBufferFactoryFromSnapshot(snapshot: model.ITextSnapsho
return builder.finish();
}
export function createTextBuffer(value: string | model.ITextBufferFactory, defaultEOL: model.DefaultEndOfLine): model.ITextBuffer {
export function createTextBuffer(value: string | model.ITextBufferFactory, defaultEOL: model.DefaultEndOfLine): { textBuffer: model.ITextBuffer; disposable: IDisposable; } {
const factory = (typeof value === 'string' ? createTextBufferFactory(value) : value);
return factory.create(defaultEOL);
}
......@@ -269,6 +269,7 @@ export class TextModel extends Disposable implements model.ITextModel {
private readonly _undoRedoService: IUndoRedoService;
private _attachedEditorCount: number;
private _buffer: model.ITextBuffer;
private _bufferDisposable: IDisposable;
private _options: model.TextModelResolvedOptions;
private _isDisposed: boolean;
......@@ -329,7 +330,9 @@ export class TextModel extends Disposable implements model.ITextModel {
this._undoRedoService = undoRedoService;
this._attachedEditorCount = 0;
this._buffer = createTextBuffer(source, creationOptions.defaultEOL);
const { textBuffer, disposable } = createTextBuffer(source, creationOptions.defaultEOL);
this._buffer = textBuffer;
this._bufferDisposable = disposable;
this._options = TextModel.resolveOptions(this._buffer, creationOptions);
......@@ -387,6 +390,7 @@ export class TextModel extends Disposable implements model.ITextModel {
this._tokenization.dispose();
this._isDisposed = true;
super.dispose();
this._bufferDisposable.dispose();
this._isDisposing = false;
// Manually release reference to previous text buffer to avoid large leaks
// in case someone leaks a TextModel reference
......@@ -426,8 +430,8 @@ export class TextModel extends Disposable implements model.ITextModel {
return;
}
const textBuffer = createTextBuffer(value, this._options.defaultEOL);
this.setValueFromTextBuffer(textBuffer);
const { textBuffer, disposable } = createTextBuffer(value, this._options.defaultEOL);
this._setValueFromTextBuffer(textBuffer, disposable);
}
private _createContentChanged2(range: Range, rangeOffset: number, rangeLength: number, text: string, isUndoing: boolean, isRedoing: boolean, isFlush: boolean): IModelContentChangedEvent {
......@@ -446,18 +450,16 @@ export class TextModel extends Disposable implements model.ITextModel {
};
}
public setValueFromTextBuffer(textBuffer: model.ITextBuffer): void {
private _setValueFromTextBuffer(textBuffer: model.ITextBuffer, textBufferDisposable: IDisposable): void {
this._assertNotDisposed();
if (textBuffer === null) {
// There's nothing to do
return;
}
const oldFullModelRange = this.getFullModelRange();
const oldModelValueLength = this.getValueLengthInRange(oldFullModelRange);
const endLineNumber = this.getLineCount();
const endColumn = this.getLineMaxColumn(endLineNumber);
this._buffer = textBuffer;
this._bufferDisposable.dispose();
this._bufferDisposable = textBufferDisposable;
this._increaseVersionId();
// Flush all tokens
......
......@@ -412,10 +412,11 @@ export class ModelServiceImpl extends Disposable implements IModelService {
public updateModel(model: ITextModel, value: string | ITextBufferFactory): void {
const options = this.getCreationOptions(model.getLanguageIdentifier().language, model.uri, model.isForSimpleWidget);
const textBuffer = createTextBuffer(value, options.defaultEOL);
const { textBuffer, disposable } = createTextBuffer(value, options.defaultEOL);
// Return early if the text is already set in that form
if (model.equalsTextBuffer(textBuffer)) {
disposable.dispose();
return;
}
......@@ -428,6 +429,7 @@ export class ModelServiceImpl extends Disposable implements IModelService {
() => []
);
model.pushStackElement();
disposable.dispose();
}
private static _commonPrefix(a: ILineSequence, aLen: number, aDelta: number, b: ILineSequence, bLen: number, bDelta: number): number {
......
......@@ -58,7 +58,7 @@ export class BenchmarkSuite {
let timeDiffTotal = 0;
for (let j = 0; j < this.iterations; j++) {
let factory = benchmark.buildBuffer(builder);
let buffer = factory.create(DefaultEndOfLine.LF);
let buffer = factory.create(DefaultEndOfLine.LF).textBuffer;
benchmark.preCycle(buffer);
let start = process.hrtime();
benchmark.fn(buffer);
......
......@@ -282,7 +282,7 @@ suite('PieceTreeTextBuffer._toSingleEditOperation', () => {
}
function testToSingleEditOperation(original: string[], edits: IValidatedEditOperation[], expected: IValidatedEditOperation): void {
const textBuffer = <PieceTreeTextBuffer>createTextBufferFactory(original.join('\n')).create(DefaultEndOfLine.LF);
const textBuffer = <PieceTreeTextBuffer>createTextBufferFactory(original.join('\n')).create(DefaultEndOfLine.LF).textBuffer;
const actual = textBuffer._toSingleEditOperation(edits);
assert.deepEqual(actual, expected);
......
......@@ -10,7 +10,7 @@ import { PieceTreeTextBuffer } from 'vs/editor/common/model/pieceTreeTextBuffer/
import { createTextBufferFactory } from 'vs/editor/common/model/textModel';
export function testTextBufferFactory(text: string, eol: string, mightContainNonBasicASCII: boolean, mightContainRTL: boolean): void {
const textBuffer = <PieceTreeTextBuffer>createTextBufferFactory(text).create(DefaultEndOfLine.LF);
const textBuffer = <PieceTreeTextBuffer>createTextBufferFactory(text).create(DefaultEndOfLine.LF).textBuffer;
assert.equal(textBuffer.mightContainNonBasicASCII(), mightContainNonBasicASCII);
assert.equal(textBuffer.mightContainRTL(), mightContainRTL);
......
......@@ -6,7 +6,7 @@
import { CharCode } from 'vs/base/common/charCode';
import { splitLines } from 'vs/base/common/strings';
import { Range } from 'vs/editor/common/core/range';
import { DefaultEndOfLine, ITextBuffer, ITextBufferBuilder, ValidAnnotatedEditOperation } from 'vs/editor/common/model';
import { ValidAnnotatedEditOperation } from 'vs/editor/common/model';
export function getRandomInt(min: number, max: number): number {
return Math.floor(Math.random() * (max - min + 1)) + min;
......@@ -127,25 +127,6 @@ export function generateRandomReplaces(chunks: string[], editCnt: number, search
return ops;
}
export function createMockText(lineCount: number, minColumn: number, maxColumn: number) {
let fixedEOL = getRandomEOLSequence();
let lines: string[] = [];
for (let i = 0; i < lineCount; i++) {
if (i !== 0) {
lines.push(fixedEOL);
}
lines.push(getRandomString(minColumn, maxColumn));
}
return lines.join('');
}
export function createMockBuffer(str: string, bufferBuilder: ITextBufferBuilder): ITextBuffer {
bufferBuilder.acceptChunk(str);
let bufferFactory = bufferBuilder.finish();
let buffer = bufferFactory.create(DefaultEndOfLine.LF);
return buffer;
}
export function generateRandomChunkWithLF(minLength: number, maxLength: number): string {
let length = getRandomInt(minLength, maxLength);
let r = '';
......
......@@ -158,7 +158,7 @@ function createTextBuffer(val: string[], normalizeEOL: boolean = true): PieceTre
bufferBuilder.acceptChunk(chunk);
}
let factory = bufferBuilder.finish(normalizeEOL);
return (<PieceTreeTextBuffer>factory.create(DefaultEndOfLine.LF)).getPieceTree();
return (<PieceTreeTextBuffer>factory.create(DefaultEndOfLine.LF).textBuffer).getPieceTree();
}
function assertTreeInvariants(T: PieceTreeBase): void {
......
......@@ -75,7 +75,7 @@ suite('TextModelData.fromString', () => {
}
function testTextModelDataFromString(text: string, expected: ITextBufferData): void {
const textBuffer = createTextBuffer(text, TextModel.DEFAULT_CREATION_OPTIONS.defaultEOL);
const textBuffer = createTextBuffer(text, TextModel.DEFAULT_CREATION_OPTIONS.defaultEOL).textBuffer;
let actual: ITextBufferData = {
EOL: textBuffer.getEOL(),
lines: textBuffer.getLinesContent(),
......
......@@ -71,7 +71,7 @@ suite('ModelService', () => {
'and finished with the fourth.', //29
].join('\n'),
DefaultEndOfLine.LF
);
).textBuffer;
const actual = ModelServiceImpl._computeEdits(model, textBuffer);
......@@ -97,7 +97,7 @@ suite('ModelService', () => {
'and finished with the fourth.', //29
].join('\n'),
DefaultEndOfLine.LF
);
).textBuffer;
const actual = ModelServiceImpl._computeEdits(model, textBuffer);
......@@ -125,7 +125,7 @@ suite('ModelService', () => {
'and finished with the fourth.', //29
].join('\r\n'),
DefaultEndOfLine.LF
);
).textBuffer;
const actual = ModelServiceImpl._computeEdits(model, textBuffer);
......@@ -151,7 +151,7 @@ suite('ModelService', () => {
'and finished with the fourth.', //29
].join('\r\n'),
DefaultEndOfLine.LF
);
).textBuffer;
const actual = ModelServiceImpl._computeEdits(model, textBuffer);
......@@ -186,7 +186,7 @@ suite('ModelService', () => {
''
].join('\r\n'),
DefaultEndOfLine.LF
);
).textBuffer;
const actual = ModelServiceImpl._computeEdits(model, textBuffer);
......@@ -380,7 +380,7 @@ suite('ModelService', () => {
function assertComputeEdits(lines1: string[], lines2: string[]): void {
const model = createTextModel(lines1.join('\n'));
const textBuffer = createTextBuffer(lines2.join('\n'), DefaultEndOfLine.LF);
const textBuffer = createTextBuffer(lines2.join('\n'), DefaultEndOfLine.LF).textBuffer;
// compute required edits
// let start = Date.now();
......
......@@ -104,10 +104,10 @@ flakySuite('BackupRestorer', () => {
const restorer = instantiationService.createInstance(TestBackupRestorer);
// Backup 2 normal files and 2 untitled file
await backupFileService.backup(untitledFile1, createTextBufferFactory('untitled-1').create(DefaultEndOfLine.LF).createSnapshot(false));
await backupFileService.backup(untitledFile2, createTextBufferFactory('untitled-2').create(DefaultEndOfLine.LF).createSnapshot(false));
await backupFileService.backup(fooFile, createTextBufferFactory('fooFile').create(DefaultEndOfLine.LF).createSnapshot(false));
await backupFileService.backup(barFile, createTextBufferFactory('barFile').create(DefaultEndOfLine.LF).createSnapshot(false));
await backupFileService.backup(untitledFile1, createTextBufferFactory('untitled-1').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
await backupFileService.backup(untitledFile2, createTextBufferFactory('untitled-2').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
await backupFileService.backup(fooFile, createTextBufferFactory('fooFile').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
await backupFileService.backup(barFile, createTextBufferFactory('barFile').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
// Verify backups restored and opened as dirty
await restorer.doRestoreBackups();
......
......@@ -480,7 +480,7 @@ class CellContentProvider implements ITextModelContentProvider {
create: (defaultEOL) => {
const newEOL = (defaultEOL === DefaultEndOfLine.CRLF ? '\r\n' : '\n');
(cell.textBuffer as ITextBuffer).setEOL(newEOL);
return cell.textBuffer as ITextBuffer;
return { textBuffer: cell.textBuffer as ITextBuffer, disposable: Disposable.None };
},
getFirstLineText: (limit: number) => {
return cell.textBuffer.getLineContent(1).substr(0, limit);
......
......@@ -61,7 +61,7 @@ export function truncatedArrayOfString(container: HTMLElement, outputs: string[]
const bufferBuilder = new PieceTreeTextBufferBuilder();
outputs.forEach(output => bufferBuilder.acceptChunk(output));
const factory = bufferBuilder.finish();
buffer = factory.create(DefaultEndOfLine.LF);
buffer = factory.create(DefaultEndOfLine.LF).textBuffer;
const sizeBufferLimitPosition = buffer.getPositionAt(SIZE_LIMIT);
if (sizeBufferLimitPosition.lineNumber < LINES_LIMIT) {
const truncatedText = buffer.getValueInRange(new Range(1, 1, sizeBufferLimitPosition.lineNumber, sizeBufferLimitPosition.column), EndOfLinePreference.TextDefined);
......@@ -83,7 +83,7 @@ export function truncatedArrayOfString(container: HTMLElement, outputs: string[]
const bufferBuilder = new PieceTreeTextBufferBuilder();
outputs.forEach(output => bufferBuilder.acceptChunk(output));
const factory = bufferBuilder.finish();
buffer = factory.create(DefaultEndOfLine.LF);
buffer = factory.create(DefaultEndOfLine.LF).textBuffer;
}
if (buffer.getLineCount() < LINES_LIMIT) {
......
......@@ -12,7 +12,7 @@ import { Range } from 'vs/editor/common/core/range';
import { Disposable } from 'vs/base/common/lifecycle';
import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { hash } from 'vs/base/common/hash';
import { createTextBuffer } from 'vs/editor/common/model/textModel';
import { PieceTreeTextBuffer } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer';
export class NotebookCellTextModel extends Disposable implements ICell {
private _onDidChangeOutputs = new Emitter<NotebookCellOutputsSplice[]>();
......@@ -65,7 +65,9 @@ export class NotebookCellTextModel extends Disposable implements ICell {
const builder = new PieceTreeTextBufferBuilder();
builder.acceptChunk(this._source);
const bufferFactory = builder.finish(true);
this._textBuffer = bufferFactory.create(model.DefaultEndOfLine.LF);
const { textBuffer, disposable } = bufferFactory.create(model.DefaultEndOfLine.LF);
this._textBuffer = textBuffer;
this._register(disposable);
this._register(this._textBuffer.onDidChangeContent(() => {
this._hash = null;
......@@ -174,7 +176,9 @@ export class NotebookCellTextModel extends Disposable implements ICell {
dispose() {
// Manually release reference to previous text buffer to avoid large leaks
// in case someone leaks a CellTextModel reference
this._textBuffer = createTextBuffer('', model.DefaultEndOfLine.LF);
const emptyDisposedTextBuffer = new PieceTreeTextBuffer([], '', '\n', false, false, true, true);
emptyDisposedTextBuffer.dispose();
this._textBuffer = emptyDisposedTextBuffer;
super.dispose();
}
}
......@@ -24,7 +24,7 @@ class MirrorCell {
const builder = new PieceTreeTextBufferBuilder();
builder.acceptChunk(Array.isArray(this._source) ? this._source.join('\n') : this._source);
const bufferFactory = builder.finish(true);
this._textBuffer = bufferFactory.create(model.DefaultEndOfLine.LF);
this._textBuffer = bufferFactory.create(model.DefaultEndOfLine.LF).textBuffer;
return this._textBuffer;
}
......
......@@ -77,7 +77,7 @@ export class WalkThroughSnippetContentProvider implements ITextModelContentProvi
if (i === j) { codeEditorModel = model; }
return '';
};
const textBuffer = factory.create(DefaultEndOfLine.LF);
const textBuffer = factory.create(DefaultEndOfLine.LF).textBuffer;
const lineCount = textBuffer.getLineCount();
const range = new Range(1, 1, lineCount, textBuffer.getLineLength(lineCount) + 1);
const markdown = textBuffer.getValueInRange(range, EndOfLinePreference.TextDefined);
......
......@@ -197,7 +197,7 @@ suite('BackupFileService', () => {
});
test('text file', async () => {
await service.backup(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).createSnapshot(false));
await service.backup(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1);
assert.equal(fs.existsSync(fooBackupPath), true);
assert.equal(fs.readFileSync(fooBackupPath), `${fooFile.toString()}\ntest`);
......@@ -205,7 +205,7 @@ suite('BackupFileService', () => {
});
test('text file (with version)', async () => {
await service.backup(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).createSnapshot(false), 666);
await service.backup(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false), 666);
assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1);
assert.equal(fs.existsSync(fooBackupPath), true);
assert.equal(fs.readFileSync(fooBackupPath), `${fooFile.toString()}\ntest`);
......@@ -214,7 +214,7 @@ suite('BackupFileService', () => {
});
test('text file (with meta)', async () => {
await service.backup(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).createSnapshot(false), undefined, { etag: '678', orphaned: true });
await service.backup(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false), undefined, { etag: '678', orphaned: true });
assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1);
assert.equal(fs.existsSync(fooBackupPath), true);
assert.equal(fs.readFileSync(fooBackupPath).toString(), `${fooFile.toString()} {"etag":"678","orphaned":true}\ntest`);
......@@ -222,7 +222,7 @@ suite('BackupFileService', () => {
});
test('untitled file', async () => {
await service.backup(untitledFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).createSnapshot(false));
await service.backup(untitledFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'untitled')).length, 1);
assert.equal(fs.existsSync(untitledBackupPath), true);
assert.equal(fs.readFileSync(untitledBackupPath), `${untitledFile.toString()}\ntest`);
......@@ -291,7 +291,7 @@ suite('BackupFileService', () => {
suite('discardBackup', () => {
test('text file', async () => {
await service.backup(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).createSnapshot(false));
await service.backup(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1);
assert.ok(service.hasBackupSync(fooFile));
......@@ -302,7 +302,7 @@ suite('BackupFileService', () => {
});
test('untitled file', async () => {
await service.backup(untitledFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).createSnapshot(false));
await service.backup(untitledFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'untitled')).length, 1);
await service.discardBackup(untitledFile);
assert.equal(fs.existsSync(untitledBackupPath), false);
......@@ -312,9 +312,9 @@ suite('BackupFileService', () => {
suite('discardBackups', () => {
test('text file', async () => {
await service.backup(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).createSnapshot(false));
await service.backup(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1);
await service.backup(barFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).createSnapshot(false));
await service.backup(barFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 2);
await service.discardBackups();
assert.equal(fs.existsSync(fooBackupPath), false);
......@@ -323,7 +323,7 @@ suite('BackupFileService', () => {
});
test('untitled file', async () => {
await service.backup(untitledFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).createSnapshot(false));
await service.backup(untitledFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'untitled')).length, 1);
await service.discardBackups();
assert.equal(fs.existsSync(untitledBackupPath), false);
......@@ -332,29 +332,29 @@ suite('BackupFileService', () => {
test('can backup after discarding all', async () => {
await service.discardBackups();
await service.backup(untitledFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).createSnapshot(false));
await service.backup(untitledFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.equal(fs.existsSync(workspaceBackupPath), true);
});
});
suite('getBackups', () => {
test('("file") - text file', async () => {
await service.backup(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).createSnapshot(false));
await service.backup(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
const textFiles = await service.getBackups();
assert.deepEqual(textFiles.map(f => f.fsPath), [fooFile.fsPath]);
await service.backup(barFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).createSnapshot(false));
await service.backup(barFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
const textFiles_1 = await service.getBackups();
assert.deepEqual(textFiles_1.map(f => f.fsPath), [fooFile.fsPath, barFile.fsPath]);
});
test('("file") - untitled file', async () => {
await service.backup(untitledFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).createSnapshot(false));
await service.backup(untitledFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
const textFiles = await service.getBackups();
assert.deepEqual(textFiles.map(f => f.fsPath), [untitledFile.fsPath]);
});
test('("untitled") - untitled file', async () => {
await service.backup(untitledFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).createSnapshot(false));
await service.backup(untitledFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
const textFiles = await service.getBackups();
assert.deepEqual(textFiles.map(f => f.fsPath), ['Untitled-1']);
});
......@@ -465,7 +465,7 @@ suite('BackupFileService', () => {
orphaned: false
};
await service.backup(fooFile, createTextBufferFactory(contents).create(DefaultEndOfLine.LF).createSnapshot(false), 1, meta);
await service.backup(fooFile, createTextBufferFactory(contents).create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false), 1, meta);
const fileContents = fs.readFileSync(fooBackupPath).toString();
assert.equal(fileContents.indexOf(fooFile.toString()), 0);
......@@ -476,7 +476,7 @@ suite('BackupFileService', () => {
const backup = await service.resolve(fooFile);
assert.ok(backup);
assert.equal(contents, snapshotToString(backup!.value.create(platform.isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).createSnapshot(true)));
assert.equal(contents, snapshotToString(backup!.value.create(platform.isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).textBuffer.createSnapshot(true)));
assert.ok(!backup!.meta);
});
......@@ -537,7 +537,7 @@ suite('BackupFileService', () => {
test('should ignore invalid backups', async () => {
const contents = 'test\nand more stuff';
await service.backup(fooBarFile, createTextBufferFactory(contents).create(DefaultEndOfLine.LF).createSnapshot(false), 1);
await service.backup(fooBarFile, createTextBufferFactory(contents).create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false), 1);
const backup = await service.resolve(fooBarFile);
if (!backup) {
......@@ -561,11 +561,11 @@ suite('BackupFileService', () => {
expectedMeta = meta;
}
await service.backup(resource, createTextBufferFactory(contents).create(DefaultEndOfLine.LF).createSnapshot(false), 1, meta);
await service.backup(resource, createTextBufferFactory(contents).create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false), 1, meta);
const backup = await service.resolve<IBackupTestMetaData>(resource);
assert.ok(backup);
assert.equal(contents, snapshotToString(backup!.value.create(platform.isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).createSnapshot(true)));
assert.equal(contents, snapshotToString(backup!.value.create(platform.isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).textBuffer.createSnapshot(true)));
if (expectedMeta) {
assert.equal(backup!.meta!.etag, expectedMeta.etag);
......
......@@ -216,7 +216,7 @@ export default function createSuite(params: Params) {
const resolved = await service.readStream(resource);
assert.equal(resolved.encoding, encoding);
assert.equal(snapshotToString(resolved.value.create(isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).createSnapshot(false)), expectedContent);
assert.equal(snapshotToString(resolved.value.create(isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).textBuffer.createSnapshot(false)), expectedContent);
}
test('write - use encoding (cp1252)', async () => {
......@@ -244,18 +244,18 @@ export default function createSuite(params: Params) {
async function testEncodingKeepsData(resource: URI, encoding: string, expected: string) {
let resolved = await service.readStream(resource, { encoding });
const content = snapshotToString(resolved.value.create(isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).createSnapshot(false));
const content = snapshotToString(resolved.value.create(isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.equal(content, expected);
await service.write(resource, content, { encoding });
resolved = await service.readStream(resource, { encoding });
assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.CRLF).createSnapshot(false)), content);
assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.CRLF).textBuffer.createSnapshot(false)), content);
await service.write(resource, createTextModel(content).createSnapshot(), { encoding });
resolved = await service.readStream(resource, { encoding });
assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.CRLF).createSnapshot(false)), content);
assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.CRLF).textBuffer.createSnapshot(false)), content);
}
test('write - no encoding - content as string', async () => {
......@@ -403,7 +403,7 @@ export default function createSuite(params: Params) {
const content = (await readFile(resource.fsPath)).toString();
assert.equal(
snapshotToString(result.value.create(DefaultEndOfLine.LF).createSnapshot(false)),
snapshotToString(result.value.create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false)),
snapshotToString(createTextModel(content).createSnapshot(false)));
}
......@@ -530,7 +530,7 @@ export default function createSuite(params: Params) {
const result = await service.readStream(resource, { encoding });
assert.equal(result.encoding, encoding);
const contents = snapshotToString(result.value.create(DefaultEndOfLine.LF).createSnapshot(false));
const contents = snapshotToString(result.value.create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.equal(contents.indexOf(needle), 0);
assert.ok(contents.indexOf(needle, 10) > 0);
......
......@@ -902,7 +902,7 @@ export class TestBackupFileService implements IBackupFileService {
async discardBackup(_resource: URI): Promise<void> { }
async discardBackups(): Promise<void> { }
parseBackupContent(textBufferFactory: ITextBufferFactory): string {
const textBuffer = textBufferFactory.create(DefaultEndOfLine.LF);
const textBuffer = textBufferFactory.create(DefaultEndOfLine.LF).textBuffer;
const lineCount = textBuffer.getLineCount();
const range = new Range(1, 1, lineCount, textBuffer.getLineLength(lineCount) + 1);
return textBuffer.getValueInRange(range, EndOfLinePreference.TextDefined);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册