From 9a3847feac5b9c1b86611b35aeaffab891b194ac Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 13 Jul 2017 08:13:49 -0700 Subject: [PATCH] getSingleLineStringWriter: Use try-finally, and only one stringWriter (#16751) * getSingleLineStringWriter: Use try-finally, and only one stringWriter * Use a `usingSingleLineStringWriter` helper function * Add assert --- src/compiler/checker.ts | 27 ++++++---------- src/compiler/utilities.ts | 67 +++++++++++++++++++++------------------ 2 files changed, 45 insertions(+), 49 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e454b43d4a1..45ec7f9f9b9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -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[] { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index b6f5616b7e3..79347d51f52 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -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) {