Skip to content

Commit 25af6cd

Browse files
committed
microsoft#19511 Model Builder returns RawTextProvider instead of RawText
- model creation options can now be specified at a later stage
1 parent bb18628 commit 25af6cd

22 files changed

Lines changed: 161 additions & 87 deletions

src/vs/editor/common/editorCommon.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,7 +1624,7 @@ export interface ITextModel {
16241624
* Replace the entire text buffer value contained in this model.
16251625
* @internal
16261626
*/
1627-
setValueFromRawText(newValue: IRawText): void;
1627+
setValueFromRawText(newValue: ITextSource): void;
16281628

16291629
/**
16301630
* Get the text stored in this model.
@@ -1649,7 +1649,7 @@ export interface ITextModel {
16491649
* Check if the raw text stored in this model equals another raw text.
16501650
* @internal
16511651
*/
1652-
equals(other: IRawText): boolean;
1652+
equals(other: ITextSource): boolean;
16531653

16541654
/**
16551655
* Get the text in a certain range.
@@ -2360,7 +2360,7 @@ export interface IModelContentChangedEvent {
23602360
* The raw text backing a model.
23612361
* @internal
23622362
*/
2363-
export interface IRawText {
2363+
export interface ITextSource {
23642364
/**
23652365
* The entire text length.
23662366
*/
@@ -2385,6 +2385,13 @@ export interface IRawText {
23852385
* The text contains only characters inside the ASCII range 32-126 or \t \r \n
23862386
*/
23872387
readonly isBasicASCII: boolean;
2388+
}
2389+
2390+
/**
2391+
* The raw text backing a model.
2392+
* @internal
2393+
*/
2394+
export interface IRawText extends ITextSource {
23882395
/**
23892396
* The options associated with this text.
23902397
*/

src/vs/editor/common/model/editableTextModel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export class EditableTextModel extends TextModelWithDecorations implements edito
6969
super.dispose();
7070
}
7171

72-
protected _resetValue(newValue: editorCommon.IRawText): void {
72+
protected _resetValue(newValue: editorCommon.ITextSource): void {
7373
super._resetValue(newValue);
7474

7575
// Destroy my edit history and settings

src/vs/editor/common/model/textModel.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ export class TextModel extends OrderGuaranteeEventEmitter implements editorCommo
285285
}
286286
}
287287

288-
protected _resetValue(newValue: editorCommon.IRawText): void {
288+
protected _resetValue(newValue: editorCommon.ITextSource): void {
289289
this._constructLines(newValue);
290290
this._increaseVersionId();
291291
}
@@ -303,7 +303,7 @@ export class TextModel extends OrderGuaranteeEventEmitter implements editorCommo
303303
};
304304
}
305305

306-
public equals(other: editorCommon.IRawText): boolean {
306+
public equals(other: editorCommon.ITextSource): boolean {
307307
this._assertNotDisposed();
308308
if (this._BOM !== other.BOM) {
309309
return false;
@@ -812,8 +812,8 @@ export class TextModel extends OrderGuaranteeEventEmitter implements editorCommo
812812
};
813813
}
814814

815-
protected _constructLines(rawText: editorCommon.IRawText): void {
816-
const tabSize = rawText.options.tabSize;
815+
private _constructLines(rawText: editorCommon.ITextSource): void {
816+
const tabSize = this._options.tabSize;
817817
let rawLines = rawText.lines;
818818
let modelLines: ModelLine[] = [];
819819

src/vs/editor/common/model/textModelWithDecorations.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ export class TextModelWithDecorations extends TextModelWithMarkers implements ed
165165
super.dispose();
166166
}
167167

168-
protected _resetValue(newValue: editorCommon.IRawText): void {
168+
protected _resetValue(newValue: editorCommon.ITextSource): void {
169169
super._resetValue(newValue);
170170

171171
// Destroy all my decorations

src/vs/editor/common/model/textModelWithMarkers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import { IdGenerator } from 'vs/base/common/idGenerator';
88
import { Position } from 'vs/editor/common/core/position';
9-
import { IRawText, ITextModelWithMarkers } from 'vs/editor/common/editorCommon';
9+
import { ITextSource, IRawText, ITextModelWithMarkers } from 'vs/editor/common/editorCommon';
1010
import { LineMarker } from 'vs/editor/common/model/modelLine';
1111
import { TextModelWithTokens } from 'vs/editor/common/model/textModelWithTokens';
1212
import { LanguageIdentifier } from 'vs/editor/common/modes';
@@ -39,7 +39,7 @@ export class TextModelWithMarkers extends TextModelWithTokens implements ITextMo
3939
super.dispose();
4040
}
4141

42-
protected _resetValue(newValue: IRawText): void {
42+
protected _resetValue(newValue: ITextSource): void {
4343
super._resetValue(newValue);
4444

4545
// Destroy all my markers

src/vs/editor/common/model/textModelWithTokens.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
108108
return false;
109109
}
110110

111-
protected _resetValue(newValue: editorCommon.IRawText): void {
111+
protected _resetValue(newValue: editorCommon.ITextSource): void {
112112
super._resetValue(newValue);
113113
// Cancel tokenization, clear all tokens and begin tokenizing
114114
this._resetTokenizationState();

src/vs/editor/common/services/modelService.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,18 @@ import { IMode } from 'vs/editor/common/modes';
1313

1414
export var IModelService = createDecorator<IModelService>('modelService');
1515

16+
export interface IRawTextProvider {
17+
getFirstLine(): string;
18+
toRawText(opts: ITextModelCreationOptions): IRawText;
19+
}
20+
1621
export interface IModelService {
1722
_serviceBrand: any;
1823

1924
createModel(value: string | IRawText, modeOrPromise: TPromise<IMode> | IMode, resource: URI): IModel;
2025

26+
createRawText(provider: IRawTextProvider): IRawText;
27+
2128
setMode(model: IModel, modeOrPromise: TPromise<IMode> | IMode): void;
2229

2330
destroyModel(resource: URI): void;

src/vs/editor/common/services/modelServiceImpl.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { Range } from 'vs/editor/common/core/range';
1818
import * as editorCommon from 'vs/editor/common/editorCommon';
1919
import { Model } from 'vs/editor/common/model/model';
2020
import { IMode, LanguageIdentifier } from 'vs/editor/common/modes';
21-
import { IModelService } from 'vs/editor/common/services/modelService';
21+
import { IModelService, IRawTextProvider } from 'vs/editor/common/services/modelService';
2222
import * as platform from 'vs/base/common/platform';
2323
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
2424
import { DEFAULT_INDENTATION, DEFAULT_TRIM_AUTO_WHITESPACE } from 'vs/editor/common/config/defaultConfig';
@@ -353,6 +353,11 @@ export class ModelServiceImpl implements IModelService {
353353
return modelData;
354354
}
355355

356+
public createRawText(provider: IRawTextProvider): editorCommon.IRawText {
357+
let creationOptions = this.getCreationOptions();
358+
return provider.toRawText(creationOptions);
359+
}
360+
356361
public createModel(value: string | editorCommon.IRawText, modeOrPromise: TPromise<IMode> | IMode, resource: URI): editorCommon.IModel {
357362
let modelData: ModelData;
358363

src/vs/editor/node/model/modelBuilder.ts

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,7 @@ import * as strings from 'vs/base/common/strings';
1111
import { guessIndentation } from 'vs/editor/common/model/indentationGuesser';
1212
import { TPromise } from 'vs/base/common/winjs.base';
1313
import { CharCode } from 'vs/base/common/charCode';
14-
15-
export class ModelBuilderResult {
16-
rawText: IRawText;
17-
hash: string;
18-
}
14+
import { IRawTextProvider } from 'vs/editor/common/services/modelService';
1915

2016
class ModelLineBasedBuilder {
2117

@@ -46,14 +42,63 @@ class ModelLineBasedBuilder {
4642
this.hash.update(lines.join('\n') + '\n');
4743
}
4844

49-
public finish(totalLength: number, carriageReturnCnt: number, containsRTL: boolean, isBasicASCII: boolean, opts: ITextModelCreationOptions): ModelBuilderResult {
45+
public finish(totalLength: number, carriageReturnCnt: number, containsRTL: boolean, isBasicASCII: boolean): ModelBuilderResult {
46+
return new ModelBuilderResult(this.BOM, this.lines, totalLength, carriageReturnCnt, containsRTL, isBasicASCII, this.hash.digest('hex'));
47+
}
48+
}
49+
50+
export class ModelBuilderResult implements IRawTextProvider {
51+
/**
52+
* The BOM (leading character sequence of the file).
53+
*/
54+
private readonly BOM: string;
55+
/**
56+
* The text split into lines.
57+
*/
58+
private readonly lines: string[];
59+
/**
60+
* The entire text length.
61+
*/
62+
private readonly length: number;
63+
/**
64+
* Number of lines with EOL \r\n
65+
*/
66+
private readonly carriageReturnCnt: number;
67+
/**
68+
* The text contains Unicode characters classified as "R" or "AL".
69+
*/
70+
private readonly containsRTL: boolean;
71+
/**
72+
* The text contains only characters inside the ASCII range 32-126 or \t \r \n
73+
*/
74+
private readonly isBasicASCII: boolean;
75+
/**
76+
* The content hash.
77+
*/
78+
public readonly hash: string;
79+
80+
constructor(BOM: string, lines: string[], length: number, carriageReturnCnt: number, containsRTL: boolean, isBasicASCII: boolean, hash: string) {
81+
this.BOM = BOM;
82+
this.lines = lines;
83+
this.length = length;
84+
this.carriageReturnCnt = carriageReturnCnt;
85+
this.containsRTL = containsRTL;
86+
this.isBasicASCII = isBasicASCII;
87+
this.hash = hash;
88+
}
89+
90+
public getFirstLine(): string {
91+
return this.lines[0];
92+
}
93+
94+
public toRawText(opts: ITextModelCreationOptions): IRawText {
5095

5196
let lineFeedCnt = this.lines.length - 1;
5297
let EOL = '';
5398
if (lineFeedCnt === 0) {
5499
// This is an empty file or a file with precisely one line
55100
EOL = (opts.defaultEOL === DefaultEndOfLine.LF ? '\n' : '\r\n');
56-
} else if (carriageReturnCnt > lineFeedCnt / 2) {
101+
} else if (this.carriageReturnCnt > lineFeedCnt / 2) {
57102
// More than half of the file contains \r\n ending lines
58103
EOL = '\r\n';
59104
} else {
@@ -80,16 +125,13 @@ class ModelLineBasedBuilder {
80125
}
81126

82127
return {
83-
rawText: {
84-
BOM: this.BOM,
85-
EOL: EOL,
86-
lines: this.lines,
87-
length: totalLength,
88-
containsRTL: containsRTL,
89-
isBasicASCII: isBasicASCII,
90-
options: resolvedOpts
91-
},
92-
hash: this.hash.digest('hex')
128+
BOM: this.BOM,
129+
EOL: EOL,
130+
lines: this.lines,
131+
length: this.length,
132+
containsRTL: this.containsRTL,
133+
isBasicASCII: this.isBasicASCII,
134+
options: resolvedOpts
93135
};
94136
}
95137
}
@@ -112,7 +154,7 @@ export class ModelBuilder {
112154
private containsRTL: boolean;
113155
private isBasicASCII: boolean;
114156

115-
public static fromStringStream(stream: IStringStream, options: ITextModelCreationOptions): TPromise<ModelBuilderResult> {
157+
public static fromStringStream(stream: IStringStream): TPromise<ModelBuilderResult> {
116158
return new TPromise<ModelBuilderResult>((c, e, p) => {
117159
let done = false;
118160
let builder = new ModelBuilder();
@@ -131,7 +173,7 @@ export class ModelBuilder {
131173
stream.on('end', () => {
132174
if (!done) {
133175
done = true;
134-
c(builder.finish(options));
176+
c(builder.finish());
135177
}
136178
});
137179
});
@@ -196,12 +238,12 @@ export class ModelBuilder {
196238
this.leftoverPrevChunk = lines[lines.length - 1];
197239
}
198240

199-
public finish(opts: ITextModelCreationOptions): ModelBuilderResult {
241+
public finish(): ModelBuilderResult {
200242
let finalLines = [this.leftoverPrevChunk];
201243
if (this.leftoverEndsInCR) {
202244
finalLines.push('');
203245
}
204246
this.lineBasedBuilder.acceptLines(finalLines);
205-
return this.lineBasedBuilder.finish(this.totalLength, this.totalCRCount, this.containsRTL, this.isBasicASCII, opts);
247+
return this.lineBasedBuilder.finish(this.totalLength, this.totalCRCount, this.containsRTL, this.isBasicASCII);
206248
}
207249
}

src/vs/editor/test/node/model/modelBuilder.test.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ export function testModelBuilder(chunks: string[], opts: ITextModelCreationOptio
1818
for (let i = 0, len = chunks.length; i < len; i++) {
1919
builder.acceptChunk(chunks[i]);
2020
}
21-
let actual = builder.finish(opts);
21+
let actual = builder.finish();
2222

23-
assert.deepEqual({
24-
rawText: expectedRawText,
25-
hash: expectedHash
26-
}, actual);
23+
let actualRawText = actual.toRawText(opts);
24+
let actualHash = actual.hash;
25+
26+
assert.equal(actualHash, expectedHash);
27+
assert.deepEqual(actualRawText, expectedRawText);
2728

2829
return expectedHash;
2930
}

0 commit comments

Comments
 (0)