@@ -38,13 +38,15 @@ module TypeScript.Scanner {
38
38
// _packedFullStartAndInfo:
39
39
//
40
40
// 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 000x <-- has leading trivia
41
- // 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 00x0 <-- has trailing trivia
42
- // 0000 0000 0000 0000 0000 0000 0000 0000 00xx xxxx xxxx xxxx xxxx xxxx xxxx xx00 <-- full start
41
+ // 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 00x0 <-- has leading comment (implies has leading trivia)
42
+ // 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0x00 <-- has trailing trivia
43
+ // 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 x000 <-- has trailing comment (implies has trailing trivia)
44
+ // 0000 0000 0000 0000 0000 0000 0000 0000 00xx xxxx xxxx xxxx xxxx xxxx xxxx 0000 <-- full start
43
45
// ^ ^ ^
44
46
// | | |
45
47
// Bit 64 Bit 30 Bit 1
46
48
//
47
- // This gives us 28 bits for the start of the token. At 256MB That's more than enough for
49
+ // This gives us 26 bits for the start of the token. At 64MB That's more than enough for
48
50
// any codebase.
49
51
//
50
52
// _packedFullWidthAndKind:
@@ -58,31 +60,31 @@ module TypeScript.Scanner {
58
60
// This gives us 23bit for width (or 8MB of width which should be enough for any codebase).
59
61
60
62
enum ScannerConstants {
61
- LargeTokenFullStartShift = 2 ,
63
+ LargeTokenFullStartShift = 4 ,
62
64
LargeTokenFullWidthShift = 7 ,
65
+ LargeTokenLeadingTriviaBitMask = 0x01 , // 00000001
66
+ LargeTokenLeadingCommentBitMask = 0x02 , // 00000010
67
+ LargeTokenTrailingTriviaBitMask = 0x04 , // 00000100
68
+ LargeTokenTrailingCommentBitMask = 0x08 , // 00001000
69
+ LargeTokenTriviaBitMask = 0x0F , // 00001111
63
70
64
71
FixedWidthTokenFullStartShift = 7 ,
72
+ FixedWidthTokenMaxFullStart = 0x7FFFFF , // 23 ones.
65
73
66
74
SmallTokenFullWidthShift = 7 ,
67
75
SmallTokenFullStartShift = 12 ,
76
+ SmallTokenMaxFullStart = 0x3FFFF , // 18 ones.
77
+ SmallTokenMaxFullWidth = 0x1F , // 5 ones
78
+ SmallTokenFullWidthMask = 0x1F , // 00011111
68
79
69
80
KindMask = 0x7F , // 01111111
70
81
IsVariableWidthMask = 0x80 , // 10000000
71
-
72
- LargeTokenLeadingTriviaBitMask = 0x01 , // 00000001
73
- LargeTokenTrailingTriviaBitMask = 0x02 , // 00000010
74
-
75
- SmallTokenFullWidthMask = 0x1F , // 00011111
76
-
77
- FixedWidthTokenMaxFullStart = 0x7FFFFF , // 23 ones.
78
- SmallTokenMaxFullStart = 0x3FFFF , // 18 ones.
79
- SmallTokenMaxFullWidth = 0x1F , // 5 ones
80
82
}
81
83
82
84
// Make sure our math works for packing/unpacking large fullStarts.
83
- Debug . assert ( largeTokenUnpackFullStart ( largeTokenPackFullStartAndInfo ( 1 << 28 , 1 , 1 ) ) === ( 1 << 28 ) ) ;
84
- Debug . assert ( largeTokenUnpackFullStart ( largeTokenPackFullStartAndInfo ( 3 << 27 , 0 , 1 ) ) === ( 3 << 27 ) ) ;
85
- Debug . assert ( largeTokenUnpackFullStart ( largeTokenPackFullStartAndInfo ( 10 << 25 , 1 , 0 ) ) === ( 10 << 25 ) ) ;
85
+ Debug . assert ( largeTokenUnpackFullStart ( largeTokenPackFullStartAndInfo ( 1 << 26 , 3 ) ) === ( 1 << 26 ) ) ;
86
+ Debug . assert ( largeTokenUnpackFullStart ( largeTokenPackFullStartAndInfo ( 3 << 25 , 1 ) ) === ( 3 << 25 ) ) ;
87
+ Debug . assert ( largeTokenUnpackFullStart ( largeTokenPackFullStartAndInfo ( 10 << 23 , 2 ) ) === ( 10 << 23 ) ) ;
86
88
87
89
function fixedWidthTokenPackData ( fullStart : number , kind : SyntaxKind ) {
88
90
return ( fullStart << ScannerConstants . FixedWidthTokenFullStartShift ) | kind ;
@@ -94,8 +96,8 @@ module TypeScript.Scanner {
94
96
95
97
function smallTokenPackData ( fullStart : number , fullWidth : number , kind : SyntaxKind ) {
96
98
return ( fullStart << ScannerConstants . SmallTokenFullStartShift ) |
97
- ( fullWidth << ScannerConstants . SmallTokenFullWidthShift ) |
98
- kind ;
99
+ ( fullWidth << ScannerConstants . SmallTokenFullWidthShift ) |
100
+ kind ;
99
101
}
100
102
101
103
function smallTokenUnpackFullWidth ( packedData : number ) : SyntaxKind {
@@ -106,8 +108,8 @@ module TypeScript.Scanner {
106
108
return packedData >> ScannerConstants . SmallTokenFullStartShift ;
107
109
}
108
110
109
- function largeTokenPackFullStartAndInfo ( fullStart : number , hasLeadingTriviaInfo : number , hasTrailingTriviaInfo : number ) : number {
110
- return ( fullStart << ScannerConstants . LargeTokenFullStartShift ) | hasLeadingTriviaInfo | hasTrailingTriviaInfo ;
111
+ function largeTokenPackFullStartAndInfo ( fullStart : number , triviaInfo : number ) : number {
112
+ return ( fullStart << ScannerConstants . LargeTokenFullStartShift ) | triviaInfo ;
111
113
}
112
114
113
115
function largeTokenUnpackFullWidth ( packedFullWidthAndKind : number ) {
@@ -118,12 +120,24 @@ module TypeScript.Scanner {
118
120
return packedFullStartAndInfo >> ScannerConstants . LargeTokenFullStartShift ;
119
121
}
120
122
121
- function largeTokenUnpackHasLeadingTriviaInfo ( packed : number ) : number {
122
- return packed & ScannerConstants . LargeTokenLeadingTriviaBitMask ;
123
+ function largeTokenUnpackHasLeadingTrivia ( packed : number ) : boolean {
124
+ return ( packed & ScannerConstants . LargeTokenLeadingTriviaBitMask ) !== 0 ;
125
+ }
126
+
127
+ function largeTokenUnpackHasTrailingTrivia ( packed : number ) : boolean {
128
+ return ( packed & ScannerConstants . LargeTokenTrailingTriviaBitMask ) !== 0 ;
129
+ }
130
+
131
+ function largeTokenUnpackHasLeadingComment ( packed : number ) : boolean {
132
+ return ( packed & ScannerConstants . LargeTokenLeadingCommentBitMask ) !== 0 ;
133
+ }
134
+
135
+ function largeTokenUnpackHasTrailingComment ( packed : number ) : boolean {
136
+ return ( packed & ScannerConstants . LargeTokenTrailingCommentBitMask ) !== 0 ;
123
137
}
124
138
125
- function largeTokenUnpackHasTrailingTriviaInfo ( packed : number ) : number {
126
- return packed & ScannerConstants . LargeTokenTrailingTriviaBitMask ;
139
+ function largeTokenUnpackTriviaInfo ( packed : number ) : number {
140
+ return packed & ScannerConstants . LargeTokenTriviaBitMask ;
127
141
}
128
142
129
143
var isKeywordStartCharacter : number [ ] = ArrayUtilities . createArray < number > ( CharacterCodes . maxAsciiCharacter , 0 ) ;
@@ -174,7 +188,7 @@ module TypeScript.Scanner {
174
188
175
189
var triviaScanner = createScannerInternal ( ts . ScriptTarget . ES5 , SimpleText . fromString ( "" ) , ( ) => { } ) ;
176
190
177
- interface IScannerToken extends ISyntaxToken {
191
+ interface IScannerToken extends ISyntaxToken {
178
192
}
179
193
180
194
function fillSizeInfo ( token : IScannerToken , text : ISimpleText ) : void {
@@ -256,6 +270,8 @@ module TypeScript.Scanner {
256
270
public fullStart ( ) : number { return fixedWidthTokenUnpackFullStart ( this . _packedData ) ; }
257
271
public hasLeadingTrivia ( ) : boolean { return false ; }
258
272
public hasTrailingTrivia ( ) : boolean { return false ; }
273
+ public hasLeadingComment ( ) : boolean { return false ; }
274
+ public hasTrailingComment ( ) : boolean { return false ; }
259
275
public clone ( ) : ISyntaxToken { return new FixedWidthTokenWithNoTrivia ( this . _packedData ) ; }
260
276
}
261
277
@@ -271,19 +287,18 @@ module TypeScript.Scanner {
271
287
272
288
public setFullStart ( fullStart : number ) : void {
273
289
this . _packedFullStartAndInfo = largeTokenPackFullStartAndInfo ( fullStart ,
274
- largeTokenUnpackHasLeadingTriviaInfo ( this . _packedFullStartAndInfo ) ,
275
- largeTokenUnpackHasTrailingTriviaInfo ( this . _packedFullStartAndInfo ) ) ;
290
+ largeTokenUnpackTriviaInfo ( this . _packedFullStartAndInfo ) ) ;
276
291
}
277
292
278
- private syntaxTreeText ( text : ISimpleText ) {
293
+ private syntaxTreeText ( text : ISimpleText ) {
279
294
var result = text || syntaxTree ( this ) . text ;
280
295
Debug . assert ( result ) ;
281
296
return result ;
282
297
}
283
298
284
- public isIncrementallyUnusable ( ) : boolean { return tokenIsIncrementallyUnusable ( this ) ; }
285
- public isKeywordConvertedToIdentifier ( ) : boolean { return false ; }
286
- public hasSkippedToken ( ) : boolean { return false ; }
299
+ public isIncrementallyUnusable ( ) : boolean { return tokenIsIncrementallyUnusable ( this ) ; }
300
+ public isKeywordConvertedToIdentifier ( ) : boolean { return false ; }
301
+ public hasSkippedToken ( ) : boolean { return false ; }
287
302
288
303
public fullText ( text ?: ISimpleText ) : string {
289
304
return fullText ( this , this . syntaxTreeText ( text ) ) ;
@@ -294,8 +309,8 @@ module TypeScript.Scanner {
294
309
return cachedText !== undefined ? cachedText : SyntaxFacts . getText ( this . kind ( ) ) ;
295
310
}
296
311
297
- public leadingTrivia ( text ?: ISimpleText ) : ISyntaxTriviaList { return leadingTrivia ( this , this . syntaxTreeText ( text ) ) ; }
298
- public trailingTrivia ( text ?: ISimpleText ) : ISyntaxTriviaList { return trailingTrivia ( this , this . syntaxTreeText ( text ) ) ; }
312
+ public leadingTrivia ( text ?: ISimpleText ) : ISyntaxTriviaList { return leadingTrivia ( this , this . syntaxTreeText ( text ) ) ; }
313
+ public trailingTrivia ( text ?: ISimpleText ) : ISyntaxTriviaList { return trailingTrivia ( this , this . syntaxTreeText ( text ) ) ; }
299
314
300
315
public leadingTriviaWidth ( text ?: ISimpleText ) : number {
301
316
return leadingTriviaWidth ( this , this . syntaxTreeText ( text ) ) ;
@@ -308,8 +323,10 @@ module TypeScript.Scanner {
308
323
public kind ( ) : SyntaxKind { return this . _packedFullWidthAndKind & ScannerConstants . KindMask ; }
309
324
public fullWidth ( ) : number { return largeTokenUnpackFullWidth ( this . _packedFullWidthAndKind ) ; }
310
325
public fullStart ( ) : number { return largeTokenUnpackFullStart ( this . _packedFullStartAndInfo ) ; }
311
- public hasLeadingTrivia ( ) : boolean { return largeTokenUnpackHasLeadingTriviaInfo ( this . _packedFullStartAndInfo ) !== 0 ; }
312
- public hasTrailingTrivia ( ) : boolean { return largeTokenUnpackHasTrailingTriviaInfo ( this . _packedFullStartAndInfo ) !== 0 ; }
326
+ public hasLeadingTrivia ( ) : boolean { return largeTokenUnpackHasLeadingTrivia ( this . _packedFullStartAndInfo ) ; }
327
+ public hasTrailingTrivia ( ) : boolean { return largeTokenUnpackHasTrailingTrivia ( this . _packedFullStartAndInfo ) ; }
328
+ public hasLeadingComment ( ) : boolean { return largeTokenUnpackHasLeadingComment ( this . _packedFullStartAndInfo ) ; }
329
+ public hasTrailingComment ( ) : boolean { return largeTokenUnpackHasTrailingComment ( this . _packedFullStartAndInfo ) ; }
313
330
public clone ( ) : ISyntaxToken { return new LargeScannerToken ( this . _packedFullStartAndInfo , this . _packedFullWidthAndKind , this . cachedText ) ; }
314
331
}
315
332
@@ -351,8 +368,8 @@ module TypeScript.Scanner {
351
368
}
352
369
353
370
function reset ( _text : ISimpleText , _start : number , _end : number ) {
354
- Debug . assert ( _start <= _text . length ( ) ) ;
355
- Debug . assert ( _end <= _text . length ( ) ) ;
371
+ Debug . assert ( _start <= _text . length ( ) , "Token's start was not within the bounds of text: " + _start + " - [0, " + _text . length ( ) + ")" ) ;
372
+ Debug . assert ( _end <= _text . length ( ) , "Token's end was not within the bounds of text: " + _end + " - [0, " + _text . length ( ) + ")" ) ;
356
373
357
374
if ( ! str || text !== _text ) {
358
375
text = _text ;
@@ -392,7 +409,7 @@ module TypeScript.Scanner {
392
409
else {
393
410
// inline the packing logic for perf.
394
411
var packedFullStartAndTriviaInfo = ( fullStart << ScannerConstants . LargeTokenFullStartShift ) |
395
- leadingTriviaInfo | ( trailingTriviaInfo << 1 ) ;
412
+ leadingTriviaInfo | ( trailingTriviaInfo << 2 ) ;
396
413
397
414
var packedFullWidthAndKind = ( fullWidth << ScannerConstants . LargeTokenFullWidthShift ) | kind ;
398
415
var cachedText = isFixedWidth ? undefined : text . substr ( start , end - start ) ;
@@ -505,7 +522,8 @@ module TypeScript.Scanner {
505
522
case CharacterCodes . verticalTab :
506
523
case CharacterCodes . formFeed :
507
524
index ++ ;
508
- result = 1 ;
525
+ // we have trivia
526
+ result |= 1 ;
509
527
continue ;
510
528
511
529
case CharacterCodes . carriageReturn :
@@ -516,27 +534,31 @@ module TypeScript.Scanner {
516
534
case CharacterCodes . lineFeed :
517
535
index ++ ;
518
536
537
+ // we have trivia
538
+ result |= 1 ;
539
+
519
540
// If we're consuming leading trivia, then we will continue consuming more
520
541
// trivia (including newlines) up to the first token we see. If we're
521
542
// consuming trailing trivia, then we break after the first newline we see.
522
543
if ( isTrailing ) {
523
- return 1 ;
544
+ return result ;
524
545
}
525
546
526
- result = 1 ;
527
547
continue ;
528
548
529
549
case CharacterCodes . slash :
530
550
if ( ( index + 1 ) < _end ) {
531
551
var ch2 = str . charCodeAt ( index + 1 ) ;
532
552
if ( ch2 === CharacterCodes . slash ) {
533
- result = 1 ;
553
+ // we have a comment, and we have trivia
554
+ result |= 3 ;
534
555
skipSingleLineCommentTrivia ( ) ;
535
556
continue ;
536
557
}
537
558
538
559
if ( ch2 === CharacterCodes . asterisk ) {
539
- result = 1 ;
560
+ // we have a comment, and we have trivia
561
+ result |= 3 ;
540
562
skipMultiLineCommentTrivia ( ) ;
541
563
continue ;
542
564
}
@@ -547,7 +569,7 @@ module TypeScript.Scanner {
547
569
548
570
default :
549
571
if ( ch > CharacterCodes . maxAsciiCharacter && slowScanTriviaInfo ( ch ) ) {
550
- result = 1 ;
572
+ result | = 1 ;
551
573
continue ;
552
574
}
553
575
@@ -1427,7 +1449,7 @@ module TypeScript.Scanner {
1427
1449
var fullEnd = fullStart + token . fullWidth ( ) ;
1428
1450
reset ( text , fullStart , fullEnd ) ;
1429
1451
1430
- var leadingTriviaInfo = scanTriviaInfo ( /*isTrailing: */ false ) ;
1452
+ scanTriviaInfo ( /*isTrailing: */ false ) ;
1431
1453
1432
1454
var start = index ;
1433
1455
scanSyntaxKind ( isContextualToken ( token ) ) ;
@@ -1616,6 +1638,8 @@ module TypeScript.Scanner {
1616
1638
}
1617
1639
1618
1640
function resetToPosition ( absolutePosition : number ) : void {
1641
+ Debug . assert ( absolutePosition <= text . length ( ) , "Trying to set the position outside the bounds of the text!" ) ;
1642
+
1619
1643
_absolutePosition = absolutePosition ;
1620
1644
1621
1645
// First, remove any diagnostics that came after this position.
0 commit comments