getSingleLineStringWriter: Use try-finally, and only one stringWriter (#16751)

* getSingleLineStringWriter: Use try-finally, and only one stringWriter

* Use a `usingSingleLineStringWriter` helper function

* Add assert
This commit is contained in:
Andy 2017-07-13 08:13:49 -07:00 committed by GitHub
parent 79b10081a9
commit 9a3847feac
2 changed files with 45 additions and 49 deletions

View file

@ -2285,21 +2285,15 @@ namespace ts {
}
function symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string {
const writer = getSingleLineStringWriter();
getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning);
const result = writer.string();
releaseStringWriter(writer);
return result;
return usingSingleLineStringWriter(writer => {
getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning);
});
}
function signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string {
const writer = getSingleLineStringWriter();
getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags, kind);
const result = writer.string();
releaseStringWriter(writer);
return result;
return usingSingleLineStringWriter(writer => {
getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags, kind);
});
}
function typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string {
@ -2996,12 +2990,9 @@ namespace ts {
}
function typePredicateToString(typePredicate: TypePredicate, enclosingDeclaration?: Declaration, flags?: TypeFormatFlags): string {
const writer = getSingleLineStringWriter();
getSymbolDisplayBuilder().buildTypePredicateDisplay(typePredicate, writer, enclosingDeclaration, flags);
const result = writer.string();
releaseStringWriter(writer);
return result;
return usingSingleLineStringWriter(writer => {
getSymbolDisplayBuilder().buildTypePredicateDisplay(typePredicate, writer, enclosingDeclaration, flags);
});
}
function formatUnionTypes(types: Type[]): Type[] {

View file

@ -44,42 +44,47 @@ namespace ts {
string(): string;
}
// Pool writers to avoid needing to allocate them for every symbol we write.
const stringWriters: StringSymbolWriter[] = [];
export function getSingleLineStringWriter(): StringSymbolWriter {
if (stringWriters.length === 0) {
let str = "";
const stringWriter = createSingleLineStringWriter();
let stringWriterAcquired = false;
const writeText: (text: string) => void = text => str += text;
return {
string: () => str,
writeKeyword: writeText,
writeOperator: writeText,
writePunctuation: writeText,
writeSpace: writeText,
writeStringLiteral: writeText,
writeParameter: writeText,
writeProperty: writeText,
writeSymbol: writeText,
function createSingleLineStringWriter(): StringSymbolWriter {
let str = "";
// Completely ignore indentation for string writers. And map newlines to
// a single space.
writeLine: () => str += " ",
increaseIndent: noop,
decreaseIndent: noop,
clear: () => str = "",
trackSymbol: noop,
reportInaccessibleThisError: noop,
reportPrivateInBaseOfClassExpression: noop,
};
}
const writeText: (text: string) => void = text => str += text;
return {
string: () => str,
writeKeyword: writeText,
writeOperator: writeText,
writePunctuation: writeText,
writeSpace: writeText,
writeStringLiteral: writeText,
writeParameter: writeText,
writeProperty: writeText,
writeSymbol: writeText,
return stringWriters.pop();
// Completely ignore indentation for string writers. And map newlines to
// a single space.
writeLine: () => str += " ",
increaseIndent: noop,
decreaseIndent: noop,
clear: () => str = "",
trackSymbol: noop,
reportInaccessibleThisError: noop,
reportPrivateInBaseOfClassExpression: noop,
};
}
export function releaseStringWriter(writer: StringSymbolWriter) {
writer.clear();
stringWriters.push(writer);
export function usingSingleLineStringWriter(action: (writer: StringSymbolWriter) => void): string {
try {
Debug.assert(!stringWriterAcquired);
stringWriterAcquired = true;
action(stringWriter);
return stringWriter.string();
}
finally {
stringWriter.clear();
stringWriterAcquired = false;
}
}
export function getFullWidth(node: Node) {