Skip to content

Commit 142f9da

Browse files
committed
Use char code array in createTextWriter
1 parent 96c48b7 commit 142f9da

File tree

1 file changed

+62
-21
lines changed

1 file changed

+62
-21
lines changed

src/compiler/utilities.ts

Lines changed: 62 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3932,32 +3932,66 @@ namespace ts {
39323932

39333933
export function createTextWriter(newLine: string): EmitTextWriter {
39343934
let output: string;
3935+
const pendingCharCodes: number[] = [];
3936+
let lastChar: number;
39353937
let indent: number;
39363938
let lineStart: boolean;
39373939
let lineCount: number;
39383940
let linePos: number;
3941+
let totalChars: number = 0;
39393942
let hasTrailingComment = false;
39403943

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();
39473955
}
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;
39503981
}
3982+
3983+
lineStart = linePos === totalChars;
39513984
}
39523985

39533986
function writeText(s: string) {
39543987
if (s && s.length) {
39553988
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
39583993
}
3959-
output += s;
3960-
updateLineCountAndPosFor(s);
3994+
appendRaw(s);
39613995
}
39623996
}
39633997

@@ -3978,12 +4012,14 @@ namespace ts {
39784012
lineCount = 0;
39794013
linePos = 0;
39804014
hasTrailingComment = false;
4015+
pendingCharCodes.length = 0;
4016+
lastChar = 0;
4017+
totalChars = 0;
39814018
}
39824019

39834020
function rawWrite(s: string) {
39844021
if (s !== undefined) {
3985-
output += s;
3986-
updateLineCountAndPosFor(s);
4022+
appendRaw(s);
39874023
hasTrailingComment = false;
39884024
}
39894025
}
@@ -3996,16 +4032,18 @@ namespace ts {
39964032

39974033
function writeLine(force?: boolean) {
39984034
if (!lineStart || force) {
3999-
output += newLine;
4035+
for (let i = 0, len = newLineCodes.length; i < len; i++) {
4036+
appendCharCode(newLineCodes[i]);
4037+
}
40004038
lineCount++;
4001-
linePos = output.length;
4039+
linePos = totalChars;
40024040
lineStart = true;
40034041
hasTrailingComment = false;
40044042
}
40054043
}
40064044

40074045
function getTextPosWithWriteLine() {
4008-
return lineStart ? output.length : (output.length + newLine.length);
4046+
return lineStart ? totalChars : (totalChars + newLineCodes.length);
40094047
}
40104048

40114049
reset();
@@ -4018,13 +4056,16 @@ namespace ts {
40184056
increaseIndent: () => { indent++; },
40194057
decreaseIndent: () => { indent--; },
40204058
getIndent: () => indent,
4021-
getTextPos: () => output.length,
4059+
getTextPos: () => totalChars,
40224060
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+
},
40254066
isAtStartOfLine: () => lineStart,
40264067
hasTrailingComment: () => hasTrailingComment,
4027-
hasTrailingWhitespace: () => !!output.length && isWhiteSpaceLike(output.charCodeAt(output.length - 1)),
4068+
hasTrailingWhitespace: () => !!lastChar && isWhiteSpaceLike(lastChar),
40284069
clear: reset,
40294070
reportInaccessibleThisError: noop,
40304071
reportPrivateInBaseOfClassExpression: noop,

0 commit comments

Comments
 (0)