4
4
*--------------------------------------------------------------------------------------------*/
5
5
6
6
import { IdleDeadline , runWhenIdle } from 'vs/base/common/async' ;
7
- import { onUnexpectedError } from 'vs/base/common/errors' ;
7
+ import { BugIndicatingError , onUnexpectedError } from 'vs/base/common/errors' ;
8
8
import { setTimeout0 } from 'vs/base/common/platform' ;
9
9
import { StopWatch } from 'vs/base/common/stopwatch' ;
10
10
import { countEOL } from 'vs/editor/common/core/eolCounter' ;
@@ -25,7 +25,7 @@ const enum Constants {
25
25
}
26
26
27
27
export class TokenizerWithStateStore < TState extends IState = IState > {
28
- private readonly initialState = this . tokenizationSupport . getInitialState ( ) ;
28
+ private readonly initialState = this . tokenizationSupport . getInitialState ( ) as TState ;
29
29
30
30
public readonly store : TrackingTokenizationStateStore < TState > ;
31
31
@@ -37,10 +37,11 @@ export class TokenizerWithStateStore<TState extends IState = IState> {
37
37
}
38
38
39
39
public getStartState ( lineNumber : number ) : TState | null {
40
- if ( lineNumber === 1 ) {
41
- return this . initialState as TState ;
42
- }
43
- return this . store . getEndState ( lineNumber - 1 ) ;
40
+ return this . store . getStartState ( lineNumber , this . initialState ) ;
41
+ }
42
+
43
+ public getFirstInvalidLine ( ) : { lineNumber : number ; startState : TState } | null {
44
+ return this . store . getFirstInvalidLine ( this . initialState ) ;
44
45
}
45
46
}
46
47
@@ -58,17 +59,16 @@ export class TokenizerWithStateStoreAndTextModel<TState extends IState = IState>
58
59
const languageId = this . _textModel . getLanguageId ( ) ;
59
60
60
61
while ( true ) {
61
- const nextLineNumber = this . store . getFirstInvalidEndStateLineNumber ( ) ;
62
- if ( ! nextLineNumber || nextLineNumber > lineNumber ) {
62
+ const lineToTokenize = this . getFirstInvalidLine ( ) ;
63
+ if ( ! lineToTokenize || lineToTokenize . lineNumber > lineNumber ) {
63
64
break ;
64
65
}
65
66
66
- const text = this . _textModel . getLineContent ( nextLineNumber ) ;
67
- const lineStartState = this . getStartState ( nextLineNumber ) ;
67
+ const text = this . _textModel . getLineContent ( lineToTokenize . lineNumber ) ;
68
68
69
- const r = safeTokenize ( this . _languageIdCodec , languageId , this . tokenizationSupport , text , true , lineStartState ! ) ;
70
- builder . add ( nextLineNumber , r . tokens ) ;
71
- this ! . store . setEndState ( nextLineNumber , r . endState as TState ) ;
69
+ const r = safeTokenize ( this . _languageIdCodec , languageId , this . tokenizationSupport , text , true , lineToTokenize . startState ) ;
70
+ builder . add ( lineToTokenize . lineNumber , r . tokens ) ;
71
+ this ! . store . setEndState ( lineToTokenize . lineNumber , r . endState as TState ) ;
72
72
}
73
73
}
74
74
@@ -217,12 +217,19 @@ export class TrackingTokenizationStateStore<TState extends IState> {
217
217
}
218
218
219
219
public setEndState ( lineNumber : number , state : TState ) : boolean {
220
+ if ( ! state ) {
221
+ throw new BugIndicatingError ( 'Cannot set null/undefined state' ) ;
222
+ }
223
+ if ( lineNumber > 1 && ! this . tokenizationStateStore . getEndState ( lineNumber - 1 ) ) {
224
+ throw new BugIndicatingError ( 'Cannot set state before setting previous state' ) ;
225
+ }
226
+
220
227
while ( true ) {
221
228
const min = this . _invalidEndStatesLineNumbers . min ;
222
- if ( min !== null && min <= lineNumber ) {
223
- this . _invalidEndStatesLineNumbers . removeMin ( ) ;
224
- } else {
229
+ if ( min === null || min > lineNumber ) {
225
230
break ;
231
+ } else {
232
+ this . _invalidEndStatesLineNumbers . removeMin ( ) ;
226
233
}
227
234
}
228
235
@@ -263,6 +270,21 @@ export class TrackingTokenizationStateStore<TState extends IState> {
263
270
public isTokenizationComplete ( ) : boolean {
264
271
return this . _invalidEndStatesLineNumbers . min === null ;
265
272
}
273
+
274
+ public getStartState ( lineNumber : number , initialState : TState ) : TState | null {
275
+ if ( lineNumber === 1 ) {
276
+ return initialState ;
277
+ }
278
+ return this . getEndState ( lineNumber - 1 ) ;
279
+ }
280
+
281
+ public getFirstInvalidLine ( initialState : TState ) : { lineNumber : number ; startState : TState } | null {
282
+ const lineNumber = this . getFirstInvalidEndStateLineNumber ( ) ;
283
+ if ( lineNumber === null ) {
284
+ return null ;
285
+ }
286
+ return { lineNumber, startState : this . getStartState ( lineNumber , initialState ) ! } ;
287
+ }
266
288
}
267
289
268
290
export class TokenizationStateStore < TState extends IState > {
0 commit comments