From 95a2055a7db46348184adbb9933e5f60e4d62fc4 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 3 Jul 2018 12:22:00 -0700 Subject: [PATCH] Extract semicolon-omitting writer from printer --- src/compiler/checker.ts | 5 ++- src/compiler/emitter.ts | 69 +++++++++++++++++------------------- src/compiler/types.ts | 1 + src/compiler/utilities.ts | 70 ++++++++++++++++++++++++++++++++++++- src/services/textChanges.ts | 4 +++ src/services/utilities.ts | 1 + 6 files changed, 111 insertions(+), 39 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e3a0fee79b3..445c485f30e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -763,6 +763,9 @@ namespace ts { writePunctuation(text) { return underlying.writePunctuation(text); }, + writeTrailingSemicolon(text) { + return underlying.writePunctuation(text); + }, writeSpace(text) { return underlying.writeSpace(text); }, @@ -3025,7 +3028,7 @@ namespace ts { const sig = nodeBuilder.signatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName); const printer = createPrinter({ removeComments: true, omitTrailingSemicolon: true }); const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); - printer.writeNode(EmitHint.Unspecified, sig!, /*sourceFile*/ sourceFile, writer); // TODO: GH#18217 + printer.writeNode(EmitHint.Unspecified, sig!, /*sourceFile*/ sourceFile, getTrailingSemicolonOmittingWriter(writer)); // TODO: GH#18217 return writer; } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 641c9a0953f..102b6cf1a0e 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -159,8 +159,19 @@ namespace ts { // Transform the source files const transform = transformNodes(resolver, host, compilerOptions, [sourceFileOrBundle], transformers!, /*allowDtsFiles*/ false); + const printerOptions: PrinterOptions = { + removeComments: compilerOptions.removeComments, + newLine: compilerOptions.newLine, + noEmitHelpers: compilerOptions.noEmitHelpers, + module: compilerOptions.module, + target: compilerOptions.target, + sourceMap: compilerOptions.sourceMap, + inlineSourceMap: compilerOptions.inlineSourceMap, + extendedDiagnostics: compilerOptions.extendedDiagnostics, + }; + // Create a printer to print the nodes - const printer = createPrinter({ ...compilerOptions, noEmitHelpers: compilerOptions.noEmitHelpers } as PrinterOptions, { + const printer = createPrinter(printerOptions, { // resolver hooks hasGlobalName: resolver.hasGlobalName, @@ -203,7 +214,20 @@ namespace ts { emitterDiagnostics.add(diagnostic); } } - const declarationPrinter = createPrinter({ ...compilerOptions, onlyPrintJsDocStyle: true, noEmitHelpers: true } as PrinterOptions, { + + const printerOptions: PrinterOptions = { + removeComments: compilerOptions.removeComments, + newLine: compilerOptions.newLine, + noEmitHelpers: true, + module: compilerOptions.module, + target: compilerOptions.target, + sourceMap: compilerOptions.sourceMap, + inlineSourceMap: compilerOptions.inlineSourceMap, + extendedDiagnostics: compilerOptions.extendedDiagnostics, + onlyPrintJsDocStyle: true, + }; + + const declarationPrinter = createPrinter(printerOptions, { // resolver hooks hasGlobalName: resolver.hasGlobalName, @@ -333,13 +357,6 @@ namespace ts { let writer: EmitTextWriter; let ownWriter: EmitTextWriter; let write = writeBase; - let commitPendingSemicolon: typeof commitPendingSemicolonInternal = noop; - let writeSemicolon: typeof writeSemicolonInternal = writeSemicolonInternal; - let pendingSemicolon = false; - if (printerOptions.omitTrailingSemicolon) { - commitPendingSemicolon = commitPendingSemicolonInternal; - writeSemicolon = deferWriteSemicolon; - } const syntheticParent: TextRange = { pos: -1, end: -1 }; const moduleKind = getEmitModuleKind(printerOptions); const bundledHelpers = createMap(); @@ -497,6 +514,9 @@ namespace ts { } function setWriter(output: EmitTextWriter | undefined) { + if (output && printerOptions.omitTrailingSemicolon) { + output = getTrailingSemicolonOmittingWriter(output); + } writer = output!; // TODO: GH#18217 comments.setWriter(output!); } @@ -2413,8 +2433,7 @@ namespace ts { } function emitJsxText(node: JsxText) { - commitPendingSemicolon(); - writer.writeLiteral(getTextOfNode(node, /*includeTrivia*/ true)); + writeLiteral(getTextOfNode(node, /*includeTrivia*/ true)); } function emitJsxClosingElementOrFragment(node: JsxClosingElement | JsxClosingFragment) { @@ -3014,83 +3033,59 @@ namespace ts { } } - function commitPendingSemicolonInternal() { - if (pendingSemicolon) { - writeSemicolonInternal(); - pendingSemicolon = false; - } - } - function writeLiteral(s: string) { - commitPendingSemicolon(); writer.writeLiteral(s); } function writeStringLiteral(s: string) { - commitPendingSemicolon(); writer.writeStringLiteral(s); } function writeBase(s: string) { - commitPendingSemicolon(); writer.write(s); } function writeSymbol(s: string, sym: Symbol) { - commitPendingSemicolon(); writer.writeSymbol(s, sym); } function writePunctuation(s: string) { - commitPendingSemicolon(); writer.writePunctuation(s); } - function deferWriteSemicolon() { - pendingSemicolon = true; - } - - function writeSemicolonInternal() { - writer.writePunctuation(";"); + function writeSemicolon() { + writer.writeTrailingSemicolon(";"); } function writeKeyword(s: string) { - commitPendingSemicolon(); writer.writeKeyword(s); } function writeOperator(s: string) { - commitPendingSemicolon(); writer.writeOperator(s); } function writeParameter(s: string) { - commitPendingSemicolon(); writer.writeParameter(s); } function writeSpace() { - commitPendingSemicolon(); writer.writeSpace(" "); } function writeProperty(s: string) { - commitPendingSemicolon(); writer.writeProperty(s); } function writeLine() { - commitPendingSemicolon(); writer.writeLine(); } function increaseIndent() { - commitPendingSemicolon(); writer.increaseIndent(); } function decreaseIndent() { - commitPendingSemicolon(); writer.decreaseIndent(); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 55e2b1d24ad..b5519bb4d84 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5296,6 +5296,7 @@ namespace ts { export interface EmitTextWriter extends SymbolWriter { write(s: string): void; writeTextOfNode(text: string, node: Node): void; + writeTrailingSemicolon(text: string): void; getText(): string; rawWrite(s: string): void; writeLiteral(s: string): void; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 9c933b44d01..546ed2f6261 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -73,6 +73,7 @@ namespace ts { writeParameter: writeText, writeProperty: writeText, writeSymbol: writeText, + writeTrailingSemicolon: writeText, getTextPos: () => str.length, getLine: () => 0, getColumn: () => 0, @@ -3117,7 +3118,74 @@ namespace ts { writePunctuation: write, writeSpace: write, writeStringLiteral: write, - writeSymbol: write + writeSymbol: write, + writeTrailingSemicolon: write + }; + } + + export function getTrailingSemicolonOmittingWriter(writer: EmitTextWriter): EmitTextWriter { + let pendingTrailingSemicolon = false; + + function commitPendingTrailingSemicolon() { + if (pendingTrailingSemicolon) { + writer.writeTrailingSemicolon(";"); + pendingTrailingSemicolon = false; + } + } + + return { + ...writer, + writeTrailingSemicolon() { + pendingTrailingSemicolon = true; + }, + writeLiteral(s) { + commitPendingTrailingSemicolon(); + writer.writeLiteral(s); + }, + writeStringLiteral(s) { + commitPendingTrailingSemicolon(); + writer.writeStringLiteral(s); + }, + writeSymbol(s, sym) { + commitPendingTrailingSemicolon(); + writer.writeSymbol(s, sym); + }, + writePunctuation(s) { + commitPendingTrailingSemicolon(); + writer.writePunctuation(s); + }, + writeKeyword(s) { + commitPendingTrailingSemicolon(); + writer.writeKeyword(s); + }, + writeOperator(s) { + commitPendingTrailingSemicolon(); + writer.writeOperator(s); + }, + writeParameter(s) { + commitPendingTrailingSemicolon(); + writer.writeParameter(s); + }, + writeSpace(s) { + commitPendingTrailingSemicolon(); + writer.writeSpace(s); + }, + writeProperty(s) { + commitPendingTrailingSemicolon(); + writer.writeProperty(s); + }, + writeLine() { + commitPendingTrailingSemicolon(); + writer.writeLine(); + }, + increaseIndent() { + commitPendingTrailingSemicolon(); + writer.increaseIndent(); + }, + decreaseIndent() { + commitPendingTrailingSemicolon(); + writer.decreaseIndent(); + } }; } diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 3001f5cf44e..cd6810e5dd3 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -907,6 +907,10 @@ namespace ts.textChanges { this.writer.writePunctuation(s); this.setLastNonTriviaPosition(s, /*force*/ false); } + writeTrailingSemicolon(s: string): void { + this.writer.writeTrailingSemicolon(s); + this.setLastNonTriviaPosition(s, /*force*/ false); + } writeParameter(s: string): void { this.writer.writeParameter(s); this.setLastNonTriviaPosition(s, /*force*/ false); diff --git a/src/services/utilities.ts b/src/services/utilities.ts index eb710b28dc6..058bd397b77 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1424,6 +1424,7 @@ namespace ts { writeKeyword: text => writeKind(text, SymbolDisplayPartKind.keyword), writeOperator: text => writeKind(text, SymbolDisplayPartKind.operator), writePunctuation: text => writeKind(text, SymbolDisplayPartKind.punctuation), + writeTrailingSemicolon: text => writeKind(text, SymbolDisplayPartKind.punctuation), writeSpace: text => writeKind(text, SymbolDisplayPartKind.space), writeStringLiteral: text => writeKind(text, SymbolDisplayPartKind.stringLiteral), writeParameter: text => writeKind(text, SymbolDisplayPartKind.parameterName),