Skip to content

Commit 8b61d66

Browse files
committed
Preserve newlines around parenthesized expressions
1 parent 563d223 commit 8b61d66

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

src/compiler/emitter.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2360,7 +2360,16 @@ namespace ts {
23602360

23612361
function emitParenthesizedExpression(node: ParenthesizedExpression) {
23622362
const openParenPos = emitTokenWithComment(SyntaxKind.OpenParenToken, node.pos, writePunctuation, node);
2363+
const leadingNewlines = getLeadingLineTerminatorCount(node, node.expression, ListFormat.None);
2364+
if (leadingNewlines) {
2365+
writeLinesAndIndent(leadingNewlines, /*writeLinesIfNotIndenting*/ false);
2366+
}
23632367
emitExpression(node.expression);
2368+
const trailingNewlines = getClosingLineTerminatorCount(node, node.expression, ListFormat.None);
2369+
if (trailingNewlines) {
2370+
writeLine(trailingNewlines);
2371+
}
2372+
decreaseIndentIf(leadingNewlines);
23642373
emitTokenWithComment(SyntaxKind.CloseParenToken, node.expression ? node.expression.end : openParenPos, writePunctuation, node);
23652374
}
23662375

@@ -4259,7 +4268,7 @@ namespace ts {
42594268
// previous indent values to be considered at a time. This also allows caller to just
42604269
// call this once, passing in all their appropriate indent values, instead of needing
42614270
// to call this helper function multiple times.
4262-
function decreaseIndentIf(value1: boolean | number, value2: boolean | number) {
4271+
function decreaseIndentIf(value1: boolean | number | undefined, value2?: boolean | number) {
42634272
if (value1) {
42644273
decreaseIndent();
42654274
}
@@ -4268,17 +4277,21 @@ namespace ts {
42684277
}
42694278
}
42704279

4271-
function getLeadingLineTerminatorCount(parentNode: TextRange, children: NodeArray<Node>, format: ListFormat): number {
4280+
function getLeadingLineTerminatorCount(parentNode: TextRange, children: NodeArray<Node> | Node, format: ListFormat): number {
42724281
if (format & ListFormat.PreserveLines || preserveSourceNewlines) {
42734282
if (format & ListFormat.PreferNewLine) {
42744283
return 1;
42754284
}
42764285

4277-
const firstChild = children[0];
4286+
const firstChild = isArray(children) ? children[0] : children;
42784287
if (firstChild === undefined) {
42794288
return rangeIsOnSingleLine(parentNode, currentSourceFile!) ? 0 : 1;
42804289
}
4281-
else if (!positionIsSynthesized(parentNode.pos) && !nodeIsSynthesized(firstChild) && firstChild.parent === parentNode) {
4290+
if (firstChild.kind === SyntaxKind.JsxText) {
4291+
// JsxText will be written with its leading whitespace, so don't add more manually.
4292+
return 0;
4293+
}
4294+
if (!positionIsSynthesized(parentNode.pos) && !nodeIsSynthesized(firstChild) && firstChild.parent === parentNode) {
42824295
if (preserveSourceNewlines) {
42834296
return getEffectiveLines(
42844297
includeComments => getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter(
@@ -4288,7 +4301,7 @@ namespace ts {
42884301
}
42894302
return rangeStartPositionsAreOnSameLine(parentNode, firstChild, currentSourceFile!) ? 0 : 1;
42904303
}
4291-
else if (synthesizedNodeStartsOnNewLine(firstChild, format)) {
4304+
if (synthesizedNodeStartsOnNewLine(firstChild, format)) {
42924305
return 1;
42934306
}
42944307
}
@@ -4300,6 +4313,10 @@ namespace ts {
43004313
if (previousNode === undefined || nextNode === undefined) {
43014314
return 0;
43024315
}
4316+
if (nextNode.kind === SyntaxKind.JsxText) {
4317+
// JsxText will be written with its leading whitespace, so don't add more manually.
4318+
return 0;
4319+
}
43034320
else if (!nodeIsSynthesized(previousNode) && !nodeIsSynthesized(nextNode) && previousNode.parent === nextNode.parent) {
43044321
return getEffectiveLines(
43054322
includeComments => getLinesBetweenRangeEndAndRangeStart(
@@ -4318,13 +4335,13 @@ namespace ts {
43184335
return format & ListFormat.MultiLine ? 1 : 0;
43194336
}
43204337

4321-
function getClosingLineTerminatorCount(parentNode: TextRange, children: NodeArray<Node>, format: ListFormat): number {
4338+
function getClosingLineTerminatorCount(parentNode: TextRange, children: NodeArray<Node> | Node, format: ListFormat): number {
43224339
if (format & ListFormat.PreserveLines || preserveSourceNewlines) {
43234340
if (format & ListFormat.PreferNewLine) {
43244341
return 1;
43254342
}
43264343

4327-
const lastChild = lastOrUndefined(children);
4344+
const lastChild = isArray(children) ? lastOrUndefined(children) : children;
43284345
if (lastChild === undefined) {
43294346
return rangeIsOnSingleLine(parentNode, currentSourceFile!) ? 0 : 1;
43304347
}

tests/cases/fourslash/textChangesPreserveNewlines7.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ verify.moveToNewFile({
3838
</div>
3939
</div>
4040
);
41-
}`
41+
}
42+
`
4243
}
4344
});

0 commit comments

Comments
 (0)