Let model builder return ISourceText.

Callers use ISourceText instead of IRawText or IRawTextProvider.
Model service holds the ownership of IRawText, Creation options and resolved options for model
This commit is contained in:
Sandeep Somavarapu 2017-01-31 09:00:08 +01:00
parent 38e8328ff6
commit 54aeb11780
13 changed files with 107 additions and 184 deletions

View file

@ -8,23 +8,17 @@ import Event from 'vs/base/common/event';
import URI from 'vs/base/common/uri';
import { TPromise } from 'vs/base/common/winjs.base';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IModel, IRawText, ITextModelCreationOptions } from 'vs/editor/common/editorCommon';
import { IModel, ITextSource, ITextModelCreationOptions } from 'vs/editor/common/editorCommon';
import { IMode } from 'vs/editor/common/modes';
export var IModelService = createDecorator<IModelService>('modelService');
export interface IRawTextProvider {
getFirstLine(): string;
getEntireContent(): string;
toRawText(opts: ITextModelCreationOptions): IRawText;
}
export interface IModelService {
_serviceBrand: any;
createModel(value: string | IRawTextProvider, modeOrPromise: TPromise<IMode> | IMode, resource: URI): IModel;
createModel(value: string | ITextSource, modeOrPromise: TPromise<IMode> | IMode, resource: URI): IModel;
updateModel(model: IModel, value: string | IRawTextProvider): void;
updateModel(model: IModel, value: string | ITextSource): void;
setMode(model: IModel, modeOrPromise: TPromise<IMode> | IMode): void;

View file

@ -18,12 +18,13 @@ import { Range } from 'vs/editor/common/core/range';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { Model } from 'vs/editor/common/model/model';
import { IMode, LanguageIdentifier } from 'vs/editor/common/modes';
import { IModelService, IRawTextProvider } from 'vs/editor/common/services/modelService';
import { IModelService } from 'vs/editor/common/services/modelService';
import * as platform from 'vs/base/common/platform';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { DEFAULT_INDENTATION, DEFAULT_TRIM_AUTO_WHITESPACE } from 'vs/editor/common/config/defaultConfig';
import { PLAINTEXT_LANGUAGE_IDENTIFIER } from 'vs/editor/common/modes/modesRegistry';
import { RawText } from 'vs/editor/common/model/textModel';
import { guessIndentation } from 'vs/editor/common/model/indentationGuesser';
function MODEL_ID(resource: URI): string {
return resource.toString();
@ -338,7 +339,7 @@ export class ModelServiceImpl implements IModelService {
// --- begin IModelService
private _createModelData(value: string | IRawTextProvider, languageIdentifier: LanguageIdentifier, resource: URI): ModelData {
private _createModelData(value: string | editorCommon.ITextSource, languageIdentifier: LanguageIdentifier, resource: URI): ModelData {
// create & save the model
const options = this.getCreationOptions(languageIdentifier.language);
@ -346,7 +347,8 @@ export class ModelServiceImpl implements IModelService {
if (typeof value === 'string') {
model = Model.createFromString(value, options, languageIdentifier, resource);
} else {
model = new Model(value.toRawText(options), languageIdentifier, resource);
const rawText = ModelServiceImpl.toRawText(value, options);
model = new Model(rawText, languageIdentifier, resource);
}
let modelId = MODEL_ID(model.uri);
@ -361,13 +363,50 @@ export class ModelServiceImpl implements IModelService {
return modelData;
}
public updateModel(model: editorCommon.IModel, value: string | IRawTextProvider): void {
private static toRawText(textSource: editorCommon.ITextSource, opts: editorCommon.ITextModelCreationOptions): editorCommon.IRawText {
let lineFeedCnt = textSource.lines.length - 1;
let EOL = textSource.EOL;
if (lineFeedCnt === 0) {
// This is an empty file or a file with precisely one line
EOL = (opts.defaultEOL === editorCommon.DefaultEndOfLine.LF ? '\n' : '\r\n');
}
let resolvedOpts: editorCommon.TextModelResolvedOptions;
if (opts.detectIndentation) {
let guessedIndentation = guessIndentation(textSource.lines, opts.tabSize, opts.insertSpaces);
resolvedOpts = new editorCommon.TextModelResolvedOptions({
tabSize: guessedIndentation.tabSize,
insertSpaces: guessedIndentation.insertSpaces,
trimAutoWhitespace: opts.trimAutoWhitespace,
defaultEOL: opts.defaultEOL
});
} else {
resolvedOpts = new editorCommon.TextModelResolvedOptions({
tabSize: opts.tabSize,
insertSpaces: opts.insertSpaces,
trimAutoWhitespace: opts.trimAutoWhitespace,
defaultEOL: opts.defaultEOL
});
}
return {
BOM: textSource.BOM,
EOL: EOL,
lines: textSource.lines,
length: textSource.length,
containsRTL: textSource.containsRTL,
isBasicASCII: textSource.isBasicASCII,
options: resolvedOpts
};
}
public updateModel(model: editorCommon.IModel, value: string | editorCommon.ITextSource): void {
let rawText: editorCommon.IRawText;
if (typeof value === 'string') {
rawText = RawText.fromStringWithModelOptions(value, model);
} else {
let creationOptions = this.getCreationOptions(model.getLanguageIdentifier().language);
rawText = value.toRawText(creationOptions);
rawText = ModelServiceImpl.toRawText(value, creationOptions);
}
// Return early if the text is already set in that form
@ -379,7 +418,7 @@ export class ModelServiceImpl implements IModelService {
model.setValueFromRawText(rawText);
}
public createModel(value: string | IRawTextProvider, modeOrPromise: TPromise<IMode> | IMode, resource: URI): editorCommon.IModel {
public createModel(value: string | editorCommon.ITextSource, modeOrPromise: TPromise<IMode> | IMode, resource: URI): editorCommon.IModel {
let modelData: ModelData;
if (!modeOrPromise || TPromise.is(modeOrPromise)) {

View file

@ -6,12 +6,15 @@
import { IStringStream } from 'vs/platform/files/common/files';
import * as crypto from 'crypto';
import { DefaultEndOfLine, ITextModelCreationOptions, TextModelResolvedOptions, IRawText } from 'vs/editor/common/editorCommon';
import { ITextSource } from 'vs/editor/common/editorCommon';
import * as strings from 'vs/base/common/strings';
import { guessIndentation } from 'vs/editor/common/model/indentationGuesser';
import { TPromise } from 'vs/base/common/winjs.base';
import { CharCode } from 'vs/base/common/charCode';
import { IRawTextProvider } from 'vs/editor/common/services/modelService';
export interface ModelBuilderResult {
readonly hash: string;
readonly value: ITextSource;
}
class ModelLineBasedBuilder {
@ -42,119 +45,31 @@ class ModelLineBasedBuilder {
this.hash.update(lines.join('\n') + '\n');
}
public finish(totalLength: number, carriageReturnCnt: number, containsRTL: boolean, isBasicASCII: boolean): ModelBuilderResult {
return new ModelBuilderResult(this.BOM, this.lines, totalLength, carriageReturnCnt, containsRTL, isBasicASCII, this.hash.digest('hex'));
}
}
export class ModelBuilderResult implements IRawTextProvider {
/**
* The BOM (leading character sequence of the file).
*/
private readonly BOM: string;
/**
* The text split into lines.
*/
private readonly lines: string[];
/**
* The entire text length.
*/
private readonly length: number;
/**
* Number of lines with EOL \r\n
*/
private readonly carriageReturnCnt: number;
/**
* The text contains Unicode characters classified as "R" or "AL".
*/
private readonly containsRTL: boolean;
/**
* The text contains only characters inside the ASCII range 32-126 or \t \r \n
*/
private readonly isBasicASCII: boolean;
/**
* The content hash.
*/
public readonly hash: string;
constructor(BOM: string, lines: string[], length: number, carriageReturnCnt: number, containsRTL: boolean, isBasicASCII: boolean, hash: string) {
this.BOM = BOM;
this.lines = lines;
this.length = length;
this.carriageReturnCnt = carriageReturnCnt;
this.containsRTL = containsRTL;
this.isBasicASCII = isBasicASCII;
this.hash = hash;
}
public getEntireContent(): string {
public finish(length: number, carriageReturnCnt: number, containsRTL: boolean, isBasicASCII: boolean): ModelBuilderResult {
let lineFeedCnt = this.lines.length - 1;
if (lineFeedCnt === 0) {
// Just one line, EOL does not matter
return this.lines[0];
}
let EOL = '';
if (this.carriageReturnCnt > lineFeedCnt / 2) {
if (carriageReturnCnt > lineFeedCnt / 2) {
// More than half of the file contains \r\n ending lines
EOL = '\r\n';
} else {
// At least one line more ends in \n
EOL = '\n';
}
return this.lines.join(EOL);
}
public getFirstLine(): string {
return this.lines[0];
}
public toRawText(opts: ITextModelCreationOptions): IRawText {
let lineFeedCnt = this.lines.length - 1;
let EOL = '';
if (lineFeedCnt === 0) {
// This is an empty file or a file with precisely one line
EOL = (opts.defaultEOL === DefaultEndOfLine.LF ? '\n' : '\r\n');
} else if (this.carriageReturnCnt > lineFeedCnt / 2) {
// More than half of the file contains \r\n ending lines
EOL = '\r\n';
} else {
// At least one line more ends in \n
EOL = '\n';
}
let resolvedOpts: TextModelResolvedOptions;
if (opts.detectIndentation) {
let guessedIndentation = guessIndentation(this.lines, opts.tabSize, opts.insertSpaces);
resolvedOpts = new TextModelResolvedOptions({
tabSize: guessedIndentation.tabSize,
insertSpaces: guessedIndentation.insertSpaces,
trimAutoWhitespace: opts.trimAutoWhitespace,
defaultEOL: opts.defaultEOL
});
} else {
resolvedOpts = new TextModelResolvedOptions({
tabSize: opts.tabSize,
insertSpaces: opts.insertSpaces,
trimAutoWhitespace: opts.trimAutoWhitespace,
defaultEOL: opts.defaultEOL
});
}
return {
BOM: this.BOM,
EOL: EOL,
lines: this.lines,
length: this.length,
containsRTL: this.containsRTL,
isBasicASCII: this.isBasicASCII,
options: resolvedOpts
hash: this.hash.digest('hex'),
value: {
BOM: this.BOM,
lines: this.lines,
length,
containsRTL: containsRTL,
EOL,
isBasicASCII,
}
};
}
}
export function computeHash(rawText: IRawText): string {
export function computeHash(rawText: ITextSource): string {
let hash = crypto.createHash('sha1');
for (let i = 0, len = rawText.lines.length; i < len; i++) {
hash.update(rawText.lines[i] + '\n');

View file

@ -6,13 +6,21 @@
import * as assert from 'assert';
import { ModelBuilder, computeHash } from 'vs/editor/node/model/modelBuilder';
import { ITextModelCreationOptions, IRawText } from 'vs/editor/common/editorCommon';
import { ITextModelCreationOptions, ITextSource } from 'vs/editor/common/editorCommon';
import { TextModel } from 'vs/editor/common/model/textModel';
import * as strings from 'vs/base/common/strings';
export function testModelBuilder(chunks: string[], opts: ITextModelCreationOptions = TextModel.DEFAULT_CREATION_OPTIONS): string {
let expectedRawText = TextModel.toRawText(chunks.join(''), opts);
let expectedHash = computeHash(expectedRawText);
let rawText = TextModel.toRawText(chunks.join(''), opts);
let expectedTextSource: ITextSource = {
BOM: rawText.BOM,
containsRTL: rawText.containsRTL,
EOL: rawText.EOL,
isBasicASCII: rawText.isBasicASCII,
length: rawText.length,
lines: rawText.lines
};
let expectedHash = computeHash(expectedTextSource);
let builder = new ModelBuilder();
for (let i = 0, len = chunks.length; i < len; i++) {
@ -20,24 +28,23 @@ export function testModelBuilder(chunks: string[], opts: ITextModelCreationOptio
}
let actual = builder.finish();
let actualRawText = actual.toRawText(opts);
let actualTextSource = actual.value;
let actualHash = actual.hash;
assert.equal(actualHash, expectedHash);
assert.deepEqual(actualRawText, expectedRawText);
assert.deepEqual(actualTextSource, expectedTextSource);
return expectedHash;
}
function toRawText(lines: string[]): IRawText {
function toRawText(lines: string[]): ITextSource {
return {
BOM: '',
lines: lines,
EOL: '\n',
length: 0,
containsRTL: false,
isBasicASCII: true,
options: null
isBasicASCII: true
};
}

View file

@ -5,13 +5,13 @@
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import { EndOfLinePreference, IModel } from 'vs/editor/common/editorCommon';
import { EndOfLinePreference, IModel, ITextSource } from 'vs/editor/common/editorCommon';
import { IMode } from 'vs/editor/common/modes';
import { EditorModel } from 'vs/workbench/common/editor';
import URI from 'vs/base/common/uri';
import { ITextEditorModel } from 'vs/editor/common/services/resolverService';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IRawTextProvider, IModelService } from 'vs/editor/common/services/modelService';
import { IModelService } from 'vs/editor/common/services/modelService';
import { IDisposable } from 'vs/base/common/lifecycle';
/**
@ -66,7 +66,7 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd
/**
* Creates the text editor model with the provided value, modeId (can be comma separated for multiple values) and optional resource URL.
*/
protected createTextEditorModel(value: string | IRawTextProvider, resource?: URI, modeId?: string): TPromise<EditorModel> {
protected createTextEditorModel(value: string | ITextSource, resource?: URI, modeId?: string): TPromise<EditorModel> {
const firstLineText = this.getFirstLineText(value);
const mode = this.getOrCreateMode(this.modeService, modeId, firstLineText);
@ -76,7 +76,7 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd
});
}
private doCreateTextEditorModel(value: string | IRawTextProvider, mode: TPromise<IMode>, resource: URI): EditorModel {
private doCreateTextEditorModel(value: string | ITextSource, mode: TPromise<IMode>, resource: URI): EditorModel {
let model = resource && this.modelService.getModel(resource);
if (!model) {
model = this.modelService.createModel(value, mode, resource);
@ -94,7 +94,7 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd
return this;
}
protected getFirstLineText(value: string | IRawTextProvider): string {
protected getFirstLineText(value: string | ITextSource): string {
if (typeof value === 'string') {
const firstLineText = value.substr(0, 100);
@ -110,7 +110,7 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd
return firstLineText.substr(0, Math.min(crIndex, lfIndex));
} else {
return value.getFirstLine().substr(0, 100);
return value.lines[0].substr(0, 100);
}
}
@ -126,7 +126,7 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd
/**
* Updates the text editor model with the provided value. If the value is the same as the model has, this is a no-op.
*/
protected updateTextEditorModel(newValue: string | IRawTextProvider): void {
protected updateTextEditorModel(newValue: string | ITextSource): void {
if (!this.textEditorModel) {
return;
}

View file

@ -74,7 +74,7 @@ export class WalkThroughSnippetContentProvider implements ITextModelContentProvi
return '';
};
const markdown = content.value.getEntireContent().replace(/\r\n/g, '\n'); // TODO: Can marked digest \r\n ?
const markdown = content.value.lines.join('\n');
marked(markdown, { renderer });
const modeId = this.modeService.getModeIdForLanguageName(languageName);

View file

@ -8,7 +8,7 @@
import Uri from 'vs/base/common/uri';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { TPromise } from 'vs/base/common/winjs.base';
import { IRawTextProvider } from 'vs/editor/common/services/modelService';
import { ITextSource } from 'vs/editor/common/editorCommon';
import { IResolveContentOptions, IUpdateContentOptions } from 'vs/platform/files/common/files';
export const IBackupFileService = createDecorator<IBackupFileService>('backupFileService');
@ -58,7 +58,7 @@ export interface IBackupFileService {
* @param rawText The IRawTextProvider from a backup resource.
* @return The backup file's backed up content.
*/
parseBackupContent(rawText: IRawTextProvider): string;
parseBackupContent(textSource: ITextSource): string;
/**
* Discards the backup associated with a resource if it exists..

View file

@ -16,7 +16,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
import { IFileService } from 'vs/platform/files/common/files';
import { TPromise } from 'vs/base/common/winjs.base';
import { readToMatchingString } from 'vs/base/node/stream';
import { IRawTextProvider } from 'vs/editor/common/services/modelService';
import { ITextSource } from 'vs/editor/common/editorCommon';
import { IWindowService } from 'vs/platform/windows/common/windows';
export interface IBackupFilesModel {
@ -219,15 +219,8 @@ export class BackupFileService implements IBackupFileService {
});
}
public parseBackupContent(rawTextProvider: IRawTextProvider): string {
let text = rawTextProvider.getEntireContent();
// The first line of a backup text file is the file name
let firstLineIndex = text.indexOf('\n');
if (firstLineIndex === -1) {
return '';
}
return text.substr(firstLineIndex + 1);
public parseBackupContent(textSource: ITextSource): string {
return textSource.lines.slice(1).join(textSource.EOL); // The first line of a backup text file is the file name
}
protected getBackupResource(resource: Uri): Uri {

View file

@ -22,8 +22,6 @@ import { parseArgs } from 'vs/platform/environment/node/argv';
import { TextModel } from 'vs/editor/common/model/textModel';
import { TPromise } from 'vs/base/common/winjs.base';
import { TestWindowService } from 'vs/workbench/test/workbenchTestServices';
import { IRawTextProvider } from 'vs/editor/common/services/modelService';
import { IRawText, ITextModelCreationOptions } from 'vs/editor/common/editorCommon';
class TestEnvironmentService extends EnvironmentService {
@ -255,18 +253,7 @@ suite('BackupFileService', () => {
test('parseBackupContent', () => {
test('should separate metadata from content', () => {
const rawText = TextModel.toRawText('metadata\ncontent', TextModel.DEFAULT_CREATION_OPTIONS);
const rawTextProvider: IRawTextProvider = {
getEntireContent: (): string => {
return rawText.lines.join(rawText.EOL);
},
getFirstLine: (): string => {
return rawText.lines[0];
},
toRawText: (opts: ITextModelCreationOptions): IRawText => {
return rawText;
}
};
assert.equal(service.parseBackupContent(rawTextProvider), 'content');
assert.equal(service.parseBackupContent(rawText), 'content');
});
});
});

View file

@ -16,7 +16,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import paths = require('vs/base/common/paths');
import diagnostics = require('vs/base/common/diagnostics');
import types = require('vs/base/common/types');
import { IModelContentChangedEvent } from 'vs/editor/common/editorCommon';
import { IModelContentChangedEvent, ITextSource } from 'vs/editor/common/editorCommon';
import { IMode } from 'vs/editor/common/modes';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { ITextFileService, IAutoSaveConfiguration, ModelState, ITextFileEditorModel, IModelSaveOptions, ISaveErrorHandler, ISaveParticipant, StateChange, SaveReason, IRawTextContent } from 'vs/workbench/services/textfile/common/textfiles';
@ -27,7 +27,7 @@ import { IFileService, IFileStat, IFileOperationResult, FileOperationResult, ICo
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IMessageService, Severity } from 'vs/platform/message/common/message';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IModelService, IRawTextProvider } from 'vs/editor/common/services/modelService';
import { IModelService } from 'vs/editor/common/services/modelService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { anonymize } from 'vs/platform/telemetry/common/telemetryUtils';
import { RunOnceScheduler } from 'vs/base/common/async';
@ -355,7 +355,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
return this.doCreateTextModel(content.resource, content.value, backup);
}
private doUpdateTextModel(value: string | IRawTextProvider): TPromise<EditorModel> {
private doUpdateTextModel(value: string | ITextSource): TPromise<EditorModel> {
diag('load() - updated text editor model', this.resource, new Date());
this.setDirty(false); // Ensure we are not tracking a stale state
@ -370,7 +370,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
return TPromise.as<EditorModel>(this);
}
private doCreateTextModel(resource: URI, value: string | IRawTextProvider, backup: URI): TPromise<EditorModel> {
private doCreateTextModel(resource: URI, value: string | ITextSource, backup: URI): TPromise<EditorModel> {
diag('load() - created text editor model', this.resource, new Date());
this.createTextEditorModelPromise = this.doLoadBackup(backup).then(backupContent => {

View file

@ -7,7 +7,7 @@
import { TPromise } from 'vs/base/common/winjs.base';
import URI from 'vs/base/common/uri';
import Event from 'vs/base/common/event';
import { IRawTextProvider } from 'vs/editor/common/services/modelService';
import { ITextSource } from 'vs/editor/common/editorCommon';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IEncodingSupport, ConfirmResult } from 'vs/workbench/common/editor';
import { IBaseStat, IResolveContentOptions } from 'vs/platform/files/common/files';
@ -112,7 +112,7 @@ export interface IRawTextContent extends IBaseStat {
/**
* The line grouped content of a text file.
*/
value: IRawTextProvider;
value: ITextSource;
/**
* The line grouped logical hash of a text file.

View file

@ -65,7 +65,7 @@ export class TextFileService extends AbstractTextFileService {
mtime: streamContent.mtime,
etag: streamContent.etag,
encoding: streamContent.encoding,
value: res,
value: res.value,
valueLogicalHash: res.hash
};
return r;

View file

@ -35,7 +35,7 @@ import { InstantiationService } from 'vs/platform/instantiation/common/instantia
import { IEditorGroupService, GroupArrangement, GroupOrientation, ITabOptions } from 'vs/workbench/services/group/common/groupService';
import { TextFileService } from 'vs/workbench/services/textfile/common/textFileService';
import { FileOperationEvent, IFileService, IResolveContentOptions, IFileOperationResult, IFileStat, IImportResult, FileChangesEvent, IResolveFileOptions, IContent, IUpdateContentOptions, IStreamContent } from 'vs/platform/files/common/files';
import { IModelService, IRawTextProvider } from 'vs/editor/common/services/modelService';
import { IModelService } from 'vs/editor/common/services/modelService';
import { ModeServiceImpl } from 'vs/editor/common/services/modeServiceImpl';
import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
import { IRawTextContent, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
@ -49,7 +49,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { IWindowsService, IWindowService } from 'vs/platform/windows/common/windows';
import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace';
import { IRawText, ITextModelCreationOptions } from 'vs/editor/common/editorCommon';
import { ITextSource } from 'vs/editor/common/editorCommon';
export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput {
return instantiationService.createInstance(FileEditorInput, resource, void 0);
@ -151,25 +151,13 @@ export class TestTextFileService extends TextFileService {
return this.fileService.resolveContent(resource, options).then((content) => {
const raw = RawText.fromString(content.value, { defaultEOL: 1, detectIndentation: false, insertSpaces: false, tabSize: 4, trimAutoWhitespace: false });
const rawTextProvider: IRawTextProvider = {
getEntireContent: (): string => {
return raw.lines.join(raw.EOL);
},
getFirstLine: (): string => {
return raw.lines[0];
},
toRawText: (opts: ITextModelCreationOptions): IRawText => {
return raw;
}
};
return <IRawTextContent>{
resource: content.resource,
name: content.name,
mtime: content.mtime,
etag: content.etag,
encoding: content.encoding,
value: rawTextProvider,
value: raw,
valueLogicalHash: null
};
});
@ -726,8 +714,8 @@ export class TestBackupFileService implements IBackupFileService {
return TPromise.as([]);
}
public parseBackupContent(rawText: IRawTextProvider): string {
return rawText.getEntireContent();
public parseBackupContent(rawText: ITextSource): string {
return rawText.lines.join('\n');
}
public discardResourceBackup(resource: URI): TPromise<void> {