diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 974c168c83b..31dbd50c048 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2365,16 +2365,10 @@ namespace ts { function emitParenthesizedExpression(node: ParenthesizedExpression) { const openParenPos = emitTokenWithComment(SyntaxKind.OpenParenToken, node.pos, writePunctuation, node); - const leadingNewlines = preserveSourceNewlines && getLeadingLineTerminatorCount(node, [node.expression], ListFormat.None); - if (leadingNewlines) { - writeLinesAndIndent(leadingNewlines, /*writeLinesIfNotIndenting*/ false); - } + const indented = writeLineSeparatorsAndIndentBefore(node.expression, node); emitExpression(node.expression); - const trailingNewlines = preserveSourceNewlines && getClosingLineTerminatorCount(node, [node.expression], ListFormat.None); - if (trailingNewlines) { - writeLine(trailingNewlines); - } - decreaseIndentIf(leadingNewlines); + writeLineSeparatorsAfter(node.expression, node); + decreaseIndentIf(indented); emitTokenWithComment(SyntaxKind.CloseParenToken, node.expression ? node.expression.end : openParenPos, writePunctuation, node); } @@ -3292,12 +3286,15 @@ namespace ts { writePunctuation("<"); if (isJsxOpeningElement(node)) { + const indented = writeLineSeparatorsAndIndentBefore(node.tagName, node); emitJsxTagName(node.tagName); emitTypeArguments(node, node.typeArguments); if (node.attributes.properties && node.attributes.properties.length > 0) { writeSpace(); } emit(node.attributes); + writeLineSeparatorsAfter(node.attributes, node); + decreaseIndentIf(indented); } writePunctuation(">"); @@ -4399,6 +4396,21 @@ namespace ts { return lines; } + function writeLineSeparatorsAndIndentBefore(node: Node, parent: Node): boolean { + const leadingNewlines = preserveSourceNewlines && getLeadingLineTerminatorCount(parent, [node], ListFormat.None); + if (leadingNewlines) { + writeLinesAndIndent(leadingNewlines, /*writeLinesIfNotIndenting*/ false); + } + return !!leadingNewlines; + } + + function writeLineSeparatorsAfter(node: Node, parent: Node) { + const trailingNewlines = preserveSourceNewlines && getClosingLineTerminatorCount(parent, [node], ListFormat.None); + if (trailingNewlines) { + writeLine(trailingNewlines); + } + } + function synthesizedNodeStartsOnNewLine(node: Node, format: ListFormat) { if (nodeIsSynthesized(node)) { const startsOnNewLine = getStartsOnNewLine(node); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 9dbfaf19c56..493accb8d61 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4779,7 +4779,7 @@ namespace ts { export function getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter(pos: number, stopPos: number, sourceFile: SourceFile, includeComments?: boolean) { const startPos = skipTrivia(sourceFile.text, pos, /*stopAfterLineBreak*/ false, includeComments); const prevPos = getPreviousNonWhitespacePosition(startPos, stopPos, sourceFile); - return getLinesBetweenPositions(sourceFile, prevPos || 0, startPos); + return getLinesBetweenPositions(sourceFile, prevPos ?? stopPos, startPos); } export function getLinesBetweenPositionAndNextNonWhitespaceCharacter(pos: number, stopPos: number, sourceFile: SourceFile, includeComments?: boolean) {