@@ -3932,32 +3932,66 @@ namespace ts {
3932
3932
3933
3933
export function createTextWriter ( newLine : string ) : EmitTextWriter {
3934
3934
let output : string ;
3935
+ const pendingCharCodes : number [ ] = [ ] ;
3936
+ let lastChar : number ;
3935
3937
let indent : number ;
3936
3938
let lineStart : boolean ;
3937
3939
let lineCount : number ;
3938
3940
let linePos : number ;
3941
+ let totalChars : number = 0 ;
3939
3942
let hasTrailingComment = false ;
3940
3943
3941
- function updateLineCountAndPosFor ( s : string ) {
3942
- const lineStartsOfS = computeLineStarts ( s ) ;
3943
- if ( lineStartsOfS . length > 1 ) {
3944
- lineCount = lineCount + lineStartsOfS . length - 1 ;
3945
- linePos = output . length - s . length + last ( lineStartsOfS ) ;
3946
- lineStart = ( linePos - output . length ) === 0 ;
3944
+ const newLineCodes : number [ ] = [ ] ;
3945
+ for ( let i = 0 ; i < newLine . length ; i ++ ) {
3946
+ newLineCodes . push ( newLine . charCodeAt ( i ) ) ;
3947
+ }
3948
+
3949
+ function appendCharCode ( charCode : number ) {
3950
+ ++ totalChars ;
3951
+ lastChar = charCode ;
3952
+ pendingCharCodes . push ( charCode ) ;
3953
+ if ( pendingCharCodes . length >= 1024 ) {
3954
+ flushBuffer ( ) ;
3947
3955
}
3948
- else {
3949
- lineStart = false ;
3956
+ }
3957
+
3958
+ function flushBuffer ( ) {
3959
+ if ( pendingCharCodes . length > 0 ) {
3960
+ output += String . fromCharCode . apply ( null , pendingCharCodes ) ;
3961
+ pendingCharCodes . length = 0 ;
3962
+ }
3963
+ }
3964
+
3965
+ function appendRaw ( text : string ) {
3966
+ let lastLineStart = - 1 ;
3967
+
3968
+ const len = text . length ;
3969
+ for ( let pos = 0 ; pos < len ; pos ++ ) {
3970
+ const ch = text . charCodeAt ( pos ) ;
3971
+ appendCharCode ( ch ) ;
3972
+ // Ignore carriageReturn, since we mark the following lineFeed as the newline anyway
3973
+ if ( ch !== CharacterCodes . carriageReturn && isLineBreak ( ch ) ) {
3974
+ ++ lineCount ;
3975
+ lastLineStart = totalChars ;
3976
+ }
3977
+ }
3978
+
3979
+ if ( lastLineStart >= 0 ) {
3980
+ linePos = lastLineStart ;
3950
3981
}
3982
+
3983
+ lineStart = linePos === totalChars ;
3951
3984
}
3952
3985
3953
3986
function writeText ( s : string ) {
3954
3987
if ( s && s . length ) {
3955
3988
if ( lineStart ) {
3956
- s = getIndentString ( indent ) + s ;
3957
- lineStart = false ;
3989
+ for ( let i = 0 ; i < indent ; i ++ ) {
3990
+ appendCharCode ( CharacterCodes . space ) ;
3991
+ }
3992
+ // lineStart will be automatically cleared by the append
3958
3993
}
3959
- output += s ;
3960
- updateLineCountAndPosFor ( s ) ;
3994
+ appendRaw ( s ) ;
3961
3995
}
3962
3996
}
3963
3997
@@ -3978,12 +4012,14 @@ namespace ts {
3978
4012
lineCount = 0 ;
3979
4013
linePos = 0 ;
3980
4014
hasTrailingComment = false ;
4015
+ pendingCharCodes . length = 0 ;
4016
+ lastChar = 0 ;
4017
+ totalChars = 0 ;
3981
4018
}
3982
4019
3983
4020
function rawWrite ( s : string ) {
3984
4021
if ( s !== undefined ) {
3985
- output += s ;
3986
- updateLineCountAndPosFor ( s ) ;
4022
+ appendRaw ( s ) ;
3987
4023
hasTrailingComment = false ;
3988
4024
}
3989
4025
}
@@ -3996,16 +4032,18 @@ namespace ts {
3996
4032
3997
4033
function writeLine ( force ?: boolean ) {
3998
4034
if ( ! lineStart || force ) {
3999
- output += newLine ;
4035
+ for ( let i = 0 , len = newLineCodes . length ; i < len ; i ++ ) {
4036
+ appendCharCode ( newLineCodes [ i ] ) ;
4037
+ }
4000
4038
lineCount ++ ;
4001
- linePos = output . length ;
4039
+ linePos = totalChars ;
4002
4040
lineStart = true ;
4003
4041
hasTrailingComment = false ;
4004
4042
}
4005
4043
}
4006
4044
4007
4045
function getTextPosWithWriteLine ( ) {
4008
- return lineStart ? output . length : ( output . length + newLine . length ) ;
4046
+ return lineStart ? totalChars : ( totalChars + newLineCodes . length ) ;
4009
4047
}
4010
4048
4011
4049
reset ( ) ;
@@ -4018,13 +4056,16 @@ namespace ts {
4018
4056
increaseIndent : ( ) => { indent ++ ; } ,
4019
4057
decreaseIndent : ( ) => { indent -- ; } ,
4020
4058
getIndent : ( ) => indent ,
4021
- getTextPos : ( ) => output . length ,
4059
+ getTextPos : ( ) => totalChars ,
4022
4060
getLine : ( ) => lineCount ,
4023
- getColumn : ( ) => lineStart ? indent * getIndentSize ( ) : output . length - linePos ,
4024
- getText : ( ) => output ,
4061
+ getColumn : ( ) => lineStart ? indent * getIndentSize ( ) : totalChars - linePos ,
4062
+ getText : ( ) => {
4063
+ flushBuffer ( ) ;
4064
+ return output ;
4065
+ } ,
4025
4066
isAtStartOfLine : ( ) => lineStart ,
4026
4067
hasTrailingComment : ( ) => hasTrailingComment ,
4027
- hasTrailingWhitespace : ( ) => ! ! output . length && isWhiteSpaceLike ( output . charCodeAt ( output . length - 1 ) ) ,
4068
+ hasTrailingWhitespace : ( ) => ! ! lastChar && isWhiteSpaceLike ( lastChar ) ,
4028
4069
clear : reset ,
4029
4070
reportInaccessibleThisError : noop ,
4030
4071
reportPrivateInBaseOfClassExpression : noop ,
0 commit comments