Skip to content

Commit 3e3d88d

Browse files
committed
Fixes microsoft/monaco-editor#122: Clear all tokenization data when resetting tokenization state
1 parent b5c999e commit 3e3d88d

3 files changed

Lines changed: 76 additions & 11 deletions

File tree

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,12 @@ export class ModelLine {
160160

161161
// --- BEGIN STATE
162162

163+
public resetTokenizationState(): void {
164+
this._state = null;
165+
this._modeTransitions = null;
166+
this._lineTokens = null;
167+
}
168+
163169
public setState(state: IState): void {
164170
this._state = state;
165171
}

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

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -354,19 +354,9 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
354354
this._scheduleRetokenizeNow.cancel();
355355
this._clearTimers();
356356
for (var i = 0; i < this._lines.length; i++) {
357-
this._lines[i].setState(null);
357+
this._lines[i].resetTokenizationState();
358358
}
359-
this._initializeTokenizationState();
360-
}
361-
362-
private _clearTimers(): void {
363-
if (this._revalidateTokensTimeout !== -1) {
364-
clearTimeout(this._revalidateTokensTimeout);
365-
this._revalidateTokensTimeout = -1;
366-
}
367-
}
368359

369-
private _initializeTokenizationState(): void {
370360
// Initialize tokenization states
371361
var initialState:IState = null;
372362
if (this._mode.tokenizationSupport) {
@@ -389,6 +379,13 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
389379
this._beginBackgroundTokenization();
390380
}
391381

382+
private _clearTimers(): void {
383+
if (this._revalidateTokensTimeout !== -1) {
384+
clearTimeout(this._revalidateTokensTimeout);
385+
this._revalidateTokensTimeout = -1;
386+
}
387+
}
388+
392389
public getLineTokens(lineNumber:number, inaccurateTokensAcceptable:boolean = false): editorCommon.ILineTokens {
393390
if (lineNumber < 1 || lineNumber > this.getLineCount()) {
394391
throw new Error('Illegal value ' + lineNumber + ' for `lineNumber`');
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
'use strict';
6+
7+
import * as assert from 'assert';
8+
import {Model} from 'vs/editor/common/model/model';
9+
import {ViewLineToken} from 'vs/editor/common/core/viewLineToken';
10+
import {ITokenizationSupport} from 'vs/editor/common/modes';
11+
import {MockMode} from 'vs/editor/test/common/mocks/mockMode';
12+
13+
suite('TextModelWithTokens', () => {
14+
15+
function assertViewLineTokens(model:Model, lineNumber:number, forceTokenization:boolean, expected:ViewLineToken[]): void {
16+
let actual = model.getLineTokens(lineNumber, !forceTokenization).inflate();
17+
assert.deepEqual(actual, expected);
18+
}
19+
20+
test('Microsoft/monaco-editor#122: Unhandled Exception: TypeError: Unable to get property \'replace\' of undefined or null reference', () => {
21+
let _tokenId = 0;
22+
class IndicisiveMode extends MockMode {
23+
public tokenizationSupport:ITokenizationSupport;
24+
25+
constructor() {
26+
super();
27+
this.tokenizationSupport = {
28+
getInitialState: () => {
29+
return null;
30+
},
31+
tokenize: (line, state, offsetDelta, stopAtOffset) => {
32+
let myId = ++_tokenId;
33+
return {
34+
tokens: [{ startIndex: 0, type: 'custom.'+myId }],
35+
actualStopOffset: line.length,
36+
endState: null,
37+
modeTransitions: [],
38+
retokenize: null
39+
};
40+
}
41+
};
42+
}
43+
}
44+
let model = Model.createFromString('A model with\ntwo lines');
45+
46+
assertViewLineTokens(model, 1, true, [new ViewLineToken(0, '')]);
47+
assertViewLineTokens(model, 2, true, [new ViewLineToken(0, '')]);
48+
49+
model.setMode(new IndicisiveMode());
50+
51+
assertViewLineTokens(model, 1, true, [new ViewLineToken(0, 'custom.1')]);
52+
assertViewLineTokens(model, 2, true, [new ViewLineToken(0, 'custom.2')]);
53+
54+
model.setMode(new IndicisiveMode());
55+
56+
assertViewLineTokens(model, 1, false, [new ViewLineToken(0, '')]);
57+
assertViewLineTokens(model, 2, false, [new ViewLineToken(0, '')]);
58+
59+
model.dispose();
60+
});
61+
62+
});

0 commit comments

Comments
 (0)