Allow emitter to write multiple newlines in node lists

This commit is contained in:
Andrew Branch
2020-02-06 09:06:56 -08:00
parent 70399e146e
commit 2b9e4aabf2
4 changed files with 56 additions and 56 deletions

View File

@@ -2924,14 +2924,14 @@ namespace ts {
return false;
}
if (shouldWriteLeadingLineTerminator(body, body.statements, ListFormat.PreserveLines)
|| shouldWriteClosingLineTerminator(body, body.statements, ListFormat.PreserveLines)) {
if (getLeadingLineTerminatorCount(body, body.statements, ListFormat.PreserveLines)
|| getClosingLineTerminatorCount(body, body.statements, ListFormat.PreserveLines)) {
return false;
}
let previousStatement: Statement | undefined;
for (const statement of body.statements) {
if (shouldWriteSeparatingLineTerminator(previousStatement, statement, ListFormat.PreserveLines)) {
if (getSeparatingLineTerminatorCount(previousStatement, statement, ListFormat.PreserveLines) > 0) {
return false;
}
@@ -4002,8 +4002,9 @@ namespace ts {
// Write the opening line terminator or leading whitespace.
const mayEmitInterveningComments = (format & ListFormat.NoInterveningComments) === 0;
let shouldEmitInterveningComments = mayEmitInterveningComments;
if (shouldWriteLeadingLineTerminator(parentNode, children!, format)) { // TODO: GH#18217
writeLine();
const leadingLineTerminatorCount = getLeadingLineTerminatorCount(parentNode, children!, format); // TODO: GH#18217
if (leadingLineTerminatorCount) {
writeLine(leadingLineTerminatorCount);
shouldEmitInterveningComments = false;
}
else if (format & ListFormat.SpaceBetweenBraces) {
@@ -4042,7 +4043,8 @@ namespace ts {
recordBundleFileInternalSectionEnd(previousSourceFileTextKind);
// Write either a line terminator or whitespace to separate the elements.
if (shouldWriteSeparatingLineTerminator(previousSibling, child, format)) {
const separatingLineTerminatorCount = getSeparatingLineTerminatorCount(previousSibling, child, format);
if (separatingLineTerminatorCount > 0) {
// If a synthesized node in a single-line list starts on a new
// line, we should increase the indent.
if ((format & (ListFormat.LinesMask | ListFormat.Indented)) === ListFormat.SingleLine) {
@@ -4050,7 +4052,7 @@ namespace ts {
shouldDecreaseIndentAfterEmit = true;
}
writeLine();
writeLine(separatingLineTerminatorCount);
shouldEmitInterveningComments = false;
}
else if (previousSibling && format & ListFormat.SpaceBetweenSiblings) {
@@ -4105,8 +4107,9 @@ namespace ts {
recordBundleFileInternalSectionEnd(previousSourceFileTextKind);
// Write the closing line terminator or closing whitespace.
if (shouldWriteClosingLineTerminator(parentNode, children!, format)) {
writeLine();
const closingLineTerminatorCount = getClosingLineTerminatorCount(parentNode, children!, format);
if (closingLineTerminatorCount) {
writeLine(closingLineTerminatorCount);
}
else if (format & ListFormat.SpaceBetweenBraces) {
writeSpace();
@@ -4176,8 +4179,10 @@ namespace ts {
writer.writeProperty(s);
}
function writeLine() {
writer.writeLine();
function writeLine(count = 1) {
for (let i = 0; i < count; i++) {
writer.writeLine(i > 0);
}
}
function increaseIndent() {
@@ -4256,75 +4261,65 @@ namespace ts {
}
}
function shouldWriteLeadingLineTerminator(parentNode: TextRange, children: NodeArray<Node>, format: ListFormat) {
if (format & ListFormat.MultiLine) {
return true;
}
if (format & ListFormat.PreserveLines) {
function getLeadingLineTerminatorCount(parentNode: TextRange, children: NodeArray<Node>, format: ListFormat): number {
if (format & ListFormat.PreserveLines || printerOptions.preserveNewlines) {
if (format & ListFormat.PreferNewLine) {
return true;
return 1;
}
const firstChild = children[0];
if (firstChild === undefined) {
return !rangeIsOnSingleLine(parentNode, currentSourceFile!);
return rangeIsOnSingleLine(parentNode, currentSourceFile!) ? 0 : 1;
}
else if (positionIsSynthesized(parentNode.pos) || nodeIsSynthesized(firstChild)) {
return synthesizedNodeStartsOnNewLine(firstChild, format);
else if (!positionIsSynthesized(parentNode.pos) && !nodeIsSynthesized(firstChild)) {
return getLinesBetweenRangeEndAndRangeStart(parentNode, firstChild, currentSourceFile!);
}
else {
return !rangeStartPositionsAreOnSameLine(parentNode, firstChild, currentSourceFile!);
else if (synthesizedNodeStartsOnNewLine(firstChild, format)) {
return 1;
}
}
else {
return false;
}
return format & ListFormat.MultiLine ? 1 : 0;
}
function shouldWriteSeparatingLineTerminator(previousNode: Node | undefined, nextNode: Node, format: ListFormat) {
if (format & ListFormat.MultiLine) {
return true;
}
else if (format & ListFormat.PreserveLines) {
function getSeparatingLineTerminatorCount(previousNode: Node | undefined, nextNode: Node, format: ListFormat): number {
if (format & ListFormat.PreserveLines || printerOptions.preserveNewlines) {
if (previousNode === undefined || nextNode === undefined) {
return false;
return 0;
}
else if (nodeIsSynthesized(previousNode) || nodeIsSynthesized(nextNode)) {
return synthesizedNodeStartsOnNewLine(previousNode, format) || synthesizedNodeStartsOnNewLine(nextNode, format);
else if (!nodeIsSynthesized(previousNode) && !nodeIsSynthesized(nextNode)) {
return getLinesBetweenRangeEndAndRangeStart(previousNode, nextNode, currentSourceFile!);
}
else {
return !rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile!);
else if (synthesizedNodeStartsOnNewLine(previousNode, format) || synthesizedNodeStartsOnNewLine(nextNode, format)) {
return 1;
}
}
else {
return getStartsOnNewLine(nextNode);
else if (getStartsOnNewLine(nextNode)) {
return 1;
}
return format & ListFormat.MultiLine ? 1 : 0;
}
function shouldWriteClosingLineTerminator(parentNode: TextRange, children: NodeArray<Node>, format: ListFormat) {
if (format & ListFormat.MultiLine) {
return (format & ListFormat.NoTrailingNewLine) === 0;
}
else if (format & ListFormat.PreserveLines) {
function getClosingLineTerminatorCount(parentNode: TextRange, children: NodeArray<Node>, format: ListFormat): number {
if (format & ListFormat.PreserveLines || printerOptions.preserveNewlines) {
if (format & ListFormat.PreferNewLine) {
return true;
return 1;
}
const lastChild = lastOrUndefined(children);
if (lastChild === undefined) {
return !rangeIsOnSingleLine(parentNode, currentSourceFile!);
return rangeIsOnSingleLine(parentNode, currentSourceFile!) ? 0 : 1;
}
else if (positionIsSynthesized(parentNode.pos) || nodeIsSynthesized(lastChild)) {
return synthesizedNodeStartsOnNewLine(lastChild, format);
else if (!positionIsSynthesized(parentNode.pos) && !nodeIsSynthesized(lastChild)) {
return getLinesBetweenRangeEndAndRangeStart(parentNode, lastChild, currentSourceFile!);
}
else {
return !rangeEndPositionsAreOnSameLine(parentNode, lastChild, currentSourceFile!);
return Number(synthesizedNodeStartsOnNewLine(lastChild, format));
}
}
else {
return false;
if (format & ListFormat.MultiLine) {
return (format & ListFormat.NoTrailingNewLine) === 0 ? 1 : 0;
}
return 0;
}
function synthesizedNodeStartsOnNewLine(node: Node, format: ListFormat) {

View File

@@ -3753,7 +3753,7 @@ namespace ts {
writeParameter(text: string): void;
writeProperty(text: string): void;
writeSymbol(text: string, symbol: Symbol): void;
writeLine(): void;
writeLine(force?: boolean): void;
increaseIndent(): void;
decreaseIndent(): void;
clear(): void;
@@ -6242,6 +6242,7 @@ namespace ts {
/*@internal*/ writeBundleFileInfo?: boolean;
/*@internal*/ recordInternalSection?: boolean;
/*@internal*/ stripInternal?: boolean;
/*@internal*/ preserveNewlines?: boolean;
/*@internal*/ relativeToBuildInfo?: (path: string) => string;
}

View File

@@ -3569,8 +3569,8 @@ namespace ts {
}
}
function writeLine() {
if (!lineStart) {
function writeLine(force?: boolean) {
if (!lineStart || force) {
output += newLine;
lineCount++;
linePos = output.length;
@@ -4676,6 +4676,10 @@ namespace ts {
return positionsAreOnSameLine(range1.end, getStartPositionOfRange(range2, sourceFile), sourceFile);
}
export function getLinesBetweenRangeEndAndRangeStart(range1: TextRange, range2: TextRange, sourceFile: SourceFile) {
return getLineOfLocalPosition(sourceFile, getStartPositionOfRange(range2, sourceFile)) - getLineOfLocalPosition(sourceFile, range1.end);
}
export function isNodeArrayMultiLine(list: NodeArray<Node>, sourceFile: SourceFile): boolean {
return !positionsAreOnSameLine(list.pos, list.end, sourceFile);
}

View File

@@ -923,7 +923,7 @@ namespace ts.textChanges {
export function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLineCharacter: string): { text: string, node: Node } {
const writer = createWriter(newLineCharacter);
const newLine = newLineCharacter === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed;
createPrinter({ newLine, neverAsciiEscape: true }, writer).writeNode(EmitHint.Unspecified, node, sourceFile, writer);
createPrinter({ newLine, neverAsciiEscape: true, preserveNewlines: true }, writer).writeNode(EmitHint.Unspecified, node, sourceFile, writer);
return { text: writer.getText(), node: assignPositionsToNode(node) };
}
}
@@ -1053,8 +1053,8 @@ namespace ts.textChanges {
writer.writeSymbol(s, sym);
setLastNonTriviaPosition(s, /*force*/ false);
}
function writeLine(): void {
writer.writeLine();
function writeLine(force?: boolean): void {
writer.writeLine(force);
}
function increaseIndent(): void {
writer.increaseIndent();