@@ -23,7 +23,11 @@ module ts {
23
23
reScanSlashToken ( ) : SyntaxKind ;
24
24
reScanTemplateToken ( ) : SyntaxKind ;
25
25
scan ( ) : SyntaxKind ;
26
- setText ( text : string ) : void ;
26
+
27
+ // Sets the text for the scanner to scan. An optional subrange starting point and length
28
+ // can be provided to have the scanner only scan a portion of the text.
29
+ setText ( text : string , start ?: number , length ?: number ) : void ;
30
+
27
31
setTextPos ( textPos : number ) : void ;
28
32
// Invokes the provided callback then unconditionally restores the scanner to the state it
29
33
// was in immediately prior to invoking the callback. The result of invoking the callback
@@ -587,9 +591,10 @@ module ts {
587
591
ch > CharacterCodes . maxAsciiCharacter && isUnicodeIdentifierPart ( ch , languageVersion ) ;
588
592
}
589
593
590
- export function createScanner ( languageVersion : ScriptTarget , skipTrivia : boolean , text ?: string , onError ?: ErrorCallback ) : Scanner {
594
+ // Creates a scanner over a (possibly unspecified) range of a piece of text.
595
+ export function createScanner ( languageVersion : ScriptTarget , skipTrivia : boolean , text ?: string , onError ?: ErrorCallback , start ?: number , length ?: number ) : Scanner {
591
596
let pos : number ; // Current position (end position of text of current token)
592
- let len : number ; // Length of text
597
+ let end : number ; // end of text
593
598
let startPos : number ; // Start position of whitespace before current token
594
599
let tokenPos : number ; // Start position of text of current token
595
600
let token : SyntaxKind ;
@@ -598,6 +603,30 @@ module ts {
598
603
let hasExtendedUnicodeEscape : boolean ;
599
604
let tokenIsUnterminated : boolean ;
600
605
606
+ setText ( text , start , length ) ;
607
+
608
+ return {
609
+ getStartPos : ( ) => startPos ,
610
+ getTextPos : ( ) => pos ,
611
+ getToken : ( ) => token ,
612
+ getTokenPos : ( ) => tokenPos ,
613
+ getTokenText : ( ) => text . substring ( tokenPos , pos ) ,
614
+ getTokenValue : ( ) => tokenValue ,
615
+ hasExtendedUnicodeEscape : ( ) => hasExtendedUnicodeEscape ,
616
+ hasPrecedingLineBreak : ( ) => precedingLineBreak ,
617
+ isIdentifier : ( ) => token === SyntaxKind . Identifier || token > SyntaxKind . LastReservedWord ,
618
+ isReservedWord : ( ) => token >= SyntaxKind . FirstReservedWord && token <= SyntaxKind . LastReservedWord ,
619
+ isUnterminated : ( ) => tokenIsUnterminated ,
620
+ reScanGreaterToken,
621
+ reScanSlashToken,
622
+ reScanTemplateToken,
623
+ scan,
624
+ setText,
625
+ setTextPos,
626
+ tryScan,
627
+ lookAhead,
628
+ } ;
629
+
601
630
function error ( message : DiagnosticMessage , length ?: number ) : void {
602
631
if ( onError ) {
603
632
onError ( message , length || 0 ) ;
@@ -694,7 +723,7 @@ module ts {
694
723
let result = "" ;
695
724
let start = pos ;
696
725
while ( true ) {
697
- if ( pos >= len ) {
726
+ if ( pos >= end ) {
698
727
result += text . substring ( start , pos ) ;
699
728
tokenIsUnterminated = true ;
700
729
error ( Diagnostics . Unterminated_string_literal ) ;
@@ -736,7 +765,7 @@ module ts {
736
765
let resultingToken : SyntaxKind ;
737
766
738
767
while ( true ) {
739
- if ( pos >= len ) {
768
+ if ( pos >= end ) {
740
769
contents += text . substring ( start , pos ) ;
741
770
tokenIsUnterminated = true ;
742
771
error ( Diagnostics . Unterminated_template_literal ) ;
@@ -755,7 +784,7 @@ module ts {
755
784
}
756
785
757
786
// '${'
758
- if ( currChar === CharacterCodes . $ && pos + 1 < len && text . charCodeAt ( pos + 1 ) === CharacterCodes . openBrace ) {
787
+ if ( currChar === CharacterCodes . $ && pos + 1 < end && text . charCodeAt ( pos + 1 ) === CharacterCodes . openBrace ) {
759
788
contents += text . substring ( start , pos ) ;
760
789
pos += 2 ;
761
790
resultingToken = startedWithBacktick ? SyntaxKind . TemplateHead : SyntaxKind . TemplateMiddle ;
@@ -776,7 +805,7 @@ module ts {
776
805
contents += text . substring ( start , pos ) ;
777
806
pos ++ ;
778
807
779
- if ( pos < len && text . charCodeAt ( pos ) === CharacterCodes . lineFeed ) {
808
+ if ( pos < end && text . charCodeAt ( pos ) === CharacterCodes . lineFeed ) {
780
809
pos ++ ;
781
810
}
782
811
@@ -796,7 +825,7 @@ module ts {
796
825
797
826
function scanEscapeSequence ( ) : string {
798
827
pos ++ ;
799
- if ( pos >= len ) {
828
+ if ( pos >= end ) {
800
829
error ( Diagnostics . Unexpected_end_of_text ) ;
801
830
return "" ;
802
831
}
@@ -822,7 +851,7 @@ module ts {
822
851
return "\"" ;
823
852
case CharacterCodes . u :
824
853
// '\u{DDDDDDDD}'
825
- if ( pos < len && text . charCodeAt ( pos ) === CharacterCodes . openBrace ) {
854
+ if ( pos < end && text . charCodeAt ( pos ) === CharacterCodes . openBrace ) {
826
855
hasExtendedUnicodeEscape = true ;
827
856
pos ++ ;
828
857
return scanExtendedUnicodeEscape ( ) ;
@@ -838,7 +867,7 @@ module ts {
838
867
// when encountering a LineContinuation (i.e. a backslash and a line terminator sequence),
839
868
// the line terminator is interpreted to be "the empty code unit sequence".
840
869
case CharacterCodes . carriageReturn :
841
- if ( pos < len && text . charCodeAt ( pos ) === CharacterCodes . lineFeed ) {
870
+ if ( pos < end && text . charCodeAt ( pos ) === CharacterCodes . lineFeed ) {
842
871
pos ++ ;
843
872
}
844
873
// fall through
@@ -877,7 +906,7 @@ module ts {
877
906
isInvalidExtendedEscape = true ;
878
907
}
879
908
880
- if ( pos >= len ) {
909
+ if ( pos >= end ) {
881
910
error ( Diagnostics . Unexpected_end_of_text ) ;
882
911
isInvalidExtendedEscape = true ;
883
912
}
@@ -914,7 +943,7 @@ module ts {
914
943
// Current character is known to be a backslash. Check for Unicode escape of the form '\uXXXX'
915
944
// and return code point value if valid Unicode escape is found. Otherwise return -1.
916
945
function peekUnicodeEscape ( ) : number {
917
- if ( pos + 5 < len && text . charCodeAt ( pos + 1 ) === CharacterCodes . u ) {
946
+ if ( pos + 5 < end && text . charCodeAt ( pos + 1 ) === CharacterCodes . u ) {
918
947
let start = pos ;
919
948
pos += 2 ;
920
949
let value = scanExactNumberOfHexDigits ( 4 ) ;
@@ -927,7 +956,7 @@ module ts {
927
956
function scanIdentifierParts ( ) : string {
928
957
let result = "" ;
929
958
let start = pos ;
930
- while ( pos < len ) {
959
+ while ( pos < end ) {
931
960
let ch = text . charCodeAt ( pos ) ;
932
961
if ( isIdentifierPart ( ch ) ) {
933
962
pos ++ ;
@@ -994,7 +1023,7 @@ module ts {
994
1023
tokenIsUnterminated = false ;
995
1024
while ( true ) {
996
1025
tokenPos = pos ;
997
- if ( pos >= len ) {
1026
+ if ( pos >= end ) {
998
1027
return token = SyntaxKind . EndOfFileToken ;
999
1028
}
1000
1029
let ch = text . charCodeAt ( pos ) ;
@@ -1007,7 +1036,7 @@ module ts {
1007
1036
continue ;
1008
1037
}
1009
1038
else {
1010
- if ( ch === CharacterCodes . carriageReturn && pos + 1 < len && text . charCodeAt ( pos + 1 ) === CharacterCodes . lineFeed ) {
1039
+ if ( ch === CharacterCodes . carriageReturn && pos + 1 < end && text . charCodeAt ( pos + 1 ) === CharacterCodes . lineFeed ) {
1011
1040
// consume both CR and LF
1012
1041
pos += 2 ;
1013
1042
}
@@ -1025,7 +1054,7 @@ module ts {
1025
1054
continue ;
1026
1055
}
1027
1056
else {
1028
- while ( pos < len && isWhiteSpace ( text . charCodeAt ( pos ) ) ) {
1057
+ while ( pos < end && isWhiteSpace ( text . charCodeAt ( pos ) ) ) {
1029
1058
pos ++ ;
1030
1059
}
1031
1060
return token = SyntaxKind . WhitespaceTrivia ;
@@ -1098,7 +1127,7 @@ module ts {
1098
1127
if ( text . charCodeAt ( pos + 1 ) === CharacterCodes . slash ) {
1099
1128
pos += 2 ;
1100
1129
1101
- while ( pos < len ) {
1130
+ while ( pos < end ) {
1102
1131
if ( isLineBreak ( text . charCodeAt ( pos ) ) ) {
1103
1132
break ;
1104
1133
}
@@ -1118,7 +1147,7 @@ module ts {
1118
1147
pos += 2 ;
1119
1148
1120
1149
let commentClosed = false ;
1121
- while ( pos < len ) {
1150
+ while ( pos < end ) {
1122
1151
let ch = text . charCodeAt ( pos ) ;
1123
1152
1124
1153
if ( ch === CharacterCodes . asterisk && text . charCodeAt ( pos + 1 ) === CharacterCodes . slash ) {
@@ -1153,7 +1182,7 @@ module ts {
1153
1182
return pos ++ , token = SyntaxKind . SlashToken ;
1154
1183
1155
1184
case CharacterCodes . _0 :
1156
- if ( pos + 2 < len && ( text . charCodeAt ( pos + 1 ) === CharacterCodes . X || text . charCodeAt ( pos + 1 ) === CharacterCodes . x ) ) {
1185
+ if ( pos + 2 < end && ( text . charCodeAt ( pos + 1 ) === CharacterCodes . X || text . charCodeAt ( pos + 1 ) === CharacterCodes . x ) ) {
1157
1186
pos += 2 ;
1158
1187
let value = scanMinimumNumberOfHexDigits ( 1 ) ;
1159
1188
if ( value < 0 ) {
@@ -1163,7 +1192,7 @@ module ts {
1163
1192
tokenValue = "" + value ;
1164
1193
return token = SyntaxKind . NumericLiteral ;
1165
1194
}
1166
- else if ( pos + 2 < len && ( text . charCodeAt ( pos + 1 ) === CharacterCodes . B || text . charCodeAt ( pos + 1 ) === CharacterCodes . b ) ) {
1195
+ else if ( pos + 2 < end && ( text . charCodeAt ( pos + 1 ) === CharacterCodes . B || text . charCodeAt ( pos + 1 ) === CharacterCodes . b ) ) {
1167
1196
pos += 2 ;
1168
1197
let value = scanBinaryOrOctalDigits ( /* base */ 2 ) ;
1169
1198
if ( value < 0 ) {
@@ -1173,7 +1202,7 @@ module ts {
1173
1202
tokenValue = "" + value ;
1174
1203
return token = SyntaxKind . NumericLiteral ;
1175
1204
}
1176
- else if ( pos + 2 < len && ( text . charCodeAt ( pos + 1 ) === CharacterCodes . O || text . charCodeAt ( pos + 1 ) === CharacterCodes . o ) ) {
1205
+ else if ( pos + 2 < end && ( text . charCodeAt ( pos + 1 ) === CharacterCodes . O || text . charCodeAt ( pos + 1 ) === CharacterCodes . o ) ) {
1177
1206
pos += 2 ;
1178
1207
let value = scanBinaryOrOctalDigits ( /* base */ 8 ) ;
1179
1208
if ( value < 0 ) {
@@ -1184,7 +1213,7 @@ module ts {
1184
1213
return token = SyntaxKind . NumericLiteral ;
1185
1214
}
1186
1215
// Try to parse as an octal
1187
- if ( pos + 1 < len && isOctalDigit ( text . charCodeAt ( pos + 1 ) ) ) {
1216
+ if ( pos + 1 < end && isOctalDigit ( text . charCodeAt ( pos + 1 ) ) ) {
1188
1217
tokenValue = "" + scanOctalDigits ( ) ;
1189
1218
return token = SyntaxKind . NumericLiteral ;
1190
1219
}
@@ -1299,7 +1328,7 @@ module ts {
1299
1328
default :
1300
1329
if ( isIdentifierStart ( ch ) ) {
1301
1330
pos ++ ;
1302
- while ( pos < len && isIdentifierPart ( ch = text . charCodeAt ( pos ) ) ) pos ++ ;
1331
+ while ( pos < end && isIdentifierPart ( ch = text . charCodeAt ( pos ) ) ) pos ++ ;
1303
1332
tokenValue = text . substring ( tokenPos , pos ) ;
1304
1333
if ( ch === CharacterCodes . backslash ) {
1305
1334
tokenValue += scanIdentifierParts ( ) ;
@@ -1350,7 +1379,7 @@ module ts {
1350
1379
while ( true ) {
1351
1380
// If we reach the end of a file, or hit a newline, then this is an unterminated
1352
1381
// regex. Report error and return what we have so far.
1353
- if ( p >= len ) {
1382
+ if ( p >= end ) {
1354
1383
tokenIsUnterminated = true ;
1355
1384
error ( Diagnostics . Unterminated_regular_expression_literal )
1356
1385
break ;
@@ -1386,7 +1415,7 @@ module ts {
1386
1415
p ++ ;
1387
1416
}
1388
1417
1389
- while ( p < len && isIdentifierPart ( text . charCodeAt ( p ) ) ) {
1418
+ while ( p < end && isIdentifierPart ( text . charCodeAt ( p ) ) ) {
1390
1419
p ++ ;
1391
1420
}
1392
1421
pos = p ;
@@ -1435,43 +1464,19 @@ module ts {
1435
1464
return speculationHelper ( callback , /*isLookahead:*/ false ) ;
1436
1465
}
1437
1466
1438
- function setText ( newText : string ) {
1467
+ function setText ( newText : string , start ?: number , length ?: number ) {
1439
1468
text = newText || "" ;
1440
- len = text . length ;
1441
- setTextPos ( 0 ) ;
1469
+ end = length === undefined ? text . length : start + length ;
1470
+ setTextPos ( start || 0 ) ;
1442
1471
}
1443
1472
1444
1473
function setTextPos ( textPos : number ) {
1474
+ Debug . assert ( textPos >= 0 ) ;
1445
1475
pos = textPos ;
1446
1476
startPos = textPos ;
1447
1477
tokenPos = textPos ;
1448
1478
token = SyntaxKind . Unknown ;
1449
1479
precedingLineBreak = false ;
1450
1480
}
1451
-
1452
- setText ( text ) ;
1453
-
1454
-
1455
- return {
1456
- getStartPos : ( ) => startPos ,
1457
- getTextPos : ( ) => pos ,
1458
- getToken : ( ) => token ,
1459
- getTokenPos : ( ) => tokenPos ,
1460
- getTokenText : ( ) => text . substring ( tokenPos , pos ) ,
1461
- getTokenValue : ( ) => tokenValue ,
1462
- hasExtendedUnicodeEscape : ( ) => hasExtendedUnicodeEscape ,
1463
- hasPrecedingLineBreak : ( ) => precedingLineBreak ,
1464
- isIdentifier : ( ) => token === SyntaxKind . Identifier || token > SyntaxKind . LastReservedWord ,
1465
- isReservedWord : ( ) => token >= SyntaxKind . FirstReservedWord && token <= SyntaxKind . LastReservedWord ,
1466
- isUnterminated : ( ) => tokenIsUnterminated ,
1467
- reScanGreaterToken,
1468
- reScanSlashToken,
1469
- reScanTemplateToken,
1470
- scan,
1471
- setText,
1472
- setTextPos,
1473
- tryScan,
1474
- lookAhead,
1475
- } ;
1476
1481
}
1477
1482
}
0 commit comments