diff --git a/internal/printer/printer.go b/internal/printer/printer.go index 4f9c719793..c361aad2a4 100644 --- a/internal/printer/printer.go +++ b/internal/printer/printer.go @@ -2949,8 +2949,56 @@ func (p *Printer) emitPartiallyEmittedExpression(node *ast.PartiallyEmittedExpre } } +func (p *Printer) commentWillEmitNewLine(comment ast.CommentRange) bool { + return comment.Kind == ast.KindSingleLineCommentTrivia || comment.HasTrailingNewLine +} + func (p *Printer) willEmitLeadingNewLine(node *ast.Expression) bool { - return false // !!! check if node will emit a leading comment that contains a trailing newline + if p.currentSourceFile == nil { + return false + } + + text := p.currentSourceFile.Text() + pos := node.Pos() + + // Get leading comment ranges + var leadingCommentRanges []ast.CommentRange + for commentRange := range scanner.GetLeadingCommentRanges(p.emitContext.Factory.AsNodeFactory(), text, pos) { + leadingCommentRanges = append(leadingCommentRanges, commentRange) + } + + if len(leadingCommentRanges) > 0 { + parseNode := p.emitContext.ParseNode(node.AsNode()) + if parseNode != nil && parseNode.Parent != nil && ast.IsParenthesizedExpression(parseNode.Parent) { + return true + } + } + + // Check if any leading comment will emit a newline + for _, comment := range leadingCommentRanges { + if p.commentWillEmitNewLine(comment) { + return true + } + } + + // Check synthetic leading comments (currently stubbed out in this codebase) + // if some(getSyntheticLeadingComments(node), commentWillEmitNewLine)) return true; + + // Handle PartiallyEmittedExpression recursively + if node.Kind == ast.KindPartiallyEmittedExpression { + partiallyEmitted := node.AsPartiallyEmittedExpression() + if node.Pos() != partiallyEmitted.Expression.Pos() { + // Check trailing comments at the expression position + for trailingComment := range scanner.GetTrailingCommentRanges(p.emitContext.Factory.AsNodeFactory(), text, partiallyEmitted.Expression.Pos()) { + if p.commentWillEmitNewLine(trailingComment) { + return true + } + } + } + return p.willEmitLeadingNewLine(partiallyEmitted.Expression) + } + + return false } func (p *Printer) emitExpressionNoASI(node *ast.Expression, precedence ast.OperatorPrecedence) { diff --git a/testdata/baselines/reference/submodule/compiler/commentEmitOnParenthesizedAssertionInReturnStatement.js b/testdata/baselines/reference/submodule/compiler/commentEmitOnParenthesizedAssertionInReturnStatement.js index 2145e23e1f..735995cc15 100644 --- a/testdata/baselines/reference/submodule/compiler/commentEmitOnParenthesizedAssertionInReturnStatement.js +++ b/testdata/baselines/reference/submodule/compiler/commentEmitOnParenthesizedAssertionInReturnStatement.js @@ -21,8 +21,8 @@ export class Foo { getThing: () => Promise.resolve('') }; foo() { - return - /* TODO: Avoid using type assertions, please refactor. */ this.client - .getThing(); + return ( + /* TODO: Avoid using type assertions, please refactor. */ (this.client + .getThing())); } } diff --git a/testdata/baselines/reference/submodule/compiler/commentEmitOnParenthesizedAssertionInReturnStatement.js.diff b/testdata/baselines/reference/submodule/compiler/commentEmitOnParenthesizedAssertionInReturnStatement.js.diff index bfd8da1762..f8009bd2e6 100644 --- a/testdata/baselines/reference/submodule/compiler/commentEmitOnParenthesizedAssertionInReturnStatement.js.diff +++ b/testdata/baselines/reference/submodule/compiler/commentEmitOnParenthesizedAssertionInReturnStatement.js.diff @@ -1,13 +1,12 @@ --- old.commentEmitOnParenthesizedAssertionInReturnStatement.js +++ new.commentEmitOnParenthesizedAssertionInReturnStatement.js -@@= skipped -20, +20 lines =@@ - getThing: () => Promise.resolve('') +@@= skipped -21, +21 lines =@@ }; foo() { -- return ( -+ return - /* TODO: Avoid using type assertions, please refactor. */ this.client + return ( +- /* TODO: Avoid using type assertions, please refactor. */ this.client - .getThing()); -+ .getThing(); ++ /* TODO: Avoid using type assertions, please refactor. */ (this.client ++ .getThing())); } } \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/compiler/commentEmitOnParenthesizedAssertionInReturnStatement2.js b/testdata/baselines/reference/submodule/compiler/commentEmitOnParenthesizedAssertionInReturnStatement2.js index 8c4faa1431..174e46c505 100644 --- a/testdata/baselines/reference/submodule/compiler/commentEmitOnParenthesizedAssertionInReturnStatement2.js +++ b/testdata/baselines/reference/submodule/compiler/commentEmitOnParenthesizedAssertionInReturnStatement2.js @@ -19,8 +19,8 @@ export class Foo { getThing: () => Promise.resolve('') }; foo() { - return - /* TODO: please refactor */ this.client - .getThing(); + return ( + /* TODO: please refactor */ (this.client + .getThing())); } } diff --git a/testdata/baselines/reference/submodule/compiler/commentEmitOnParenthesizedAssertionInReturnStatement2.js.diff b/testdata/baselines/reference/submodule/compiler/commentEmitOnParenthesizedAssertionInReturnStatement2.js.diff index 0f62dee725..1304bde5e1 100644 --- a/testdata/baselines/reference/submodule/compiler/commentEmitOnParenthesizedAssertionInReturnStatement2.js.diff +++ b/testdata/baselines/reference/submodule/compiler/commentEmitOnParenthesizedAssertionInReturnStatement2.js.diff @@ -1,13 +1,12 @@ --- old.commentEmitOnParenthesizedAssertionInReturnStatement2.js +++ new.commentEmitOnParenthesizedAssertionInReturnStatement2.js -@@= skipped -18, +18 lines =@@ - getThing: () => Promise.resolve('') +@@= skipped -19, +19 lines =@@ }; foo() { -- return ( -+ return - /* TODO: please refactor */ this.client + return ( +- /* TODO: please refactor */ this.client - .getThing()); -+ .getThing(); ++ /* TODO: please refactor */ (this.client ++ .getThing())); } } \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/returnStatementNoAsiAfterTransform(target=es5).js b/testdata/baselines/reference/submodule/conformance/returnStatementNoAsiAfterTransform(target=es5).js index af3c2fde4a..75c73a97fa 100644 --- a/testdata/baselines/reference/submodule/conformance/returnStatementNoAsiAfterTransform(target=es5).js +++ b/testdata/baselines/reference/submodule/conformance/returnStatementNoAsiAfterTransform(target=es5).js @@ -67,9 +67,9 @@ function t10() { //// [returnStatementNoAsiAfterTransform.js] function t1() { - return + return ( // comment - a; + (a)); } function t2() { return @@ -102,17 +102,17 @@ function t7() { a ``; } function t8() { - return + return ( // comment - a; + (a)); } function t9() { - return + return ( // comment - a; + (a)); } function t10() { - return + return ( // comment - a; + (a)); } diff --git a/testdata/baselines/reference/submodule/conformance/returnStatementNoAsiAfterTransform(target=es5).js.diff b/testdata/baselines/reference/submodule/conformance/returnStatementNoAsiAfterTransform(target=es5).js.diff index 531a57c9ef..a2e6264226 100644 --- a/testdata/baselines/reference/submodule/conformance/returnStatementNoAsiAfterTransform(target=es5).js.diff +++ b/testdata/baselines/reference/submodule/conformance/returnStatementNoAsiAfterTransform(target=es5).js.diff @@ -9,11 +9,10 @@ - return cooked; -}; function t1() { -- return ( -+ return + return ( // comment - a); -+ a; ++ (a)); } function t2() { - return ( @@ -58,23 +57,20 @@ + a ``; } function t8() { -- return ( -+ return + return ( // comment - a); -+ a; ++ (a)); } function t9() { -- return ( -+ return + return ( // comment - a); -+ a; ++ (a)); } function t10() { -- return ( -+ return + return ( // comment - a); -+ a; ++ (a)); } \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/returnStatementNoAsiAfterTransform(target=esnext).js b/testdata/baselines/reference/submodule/conformance/returnStatementNoAsiAfterTransform(target=esnext).js index af3c2fde4a..75c73a97fa 100644 --- a/testdata/baselines/reference/submodule/conformance/returnStatementNoAsiAfterTransform(target=esnext).js +++ b/testdata/baselines/reference/submodule/conformance/returnStatementNoAsiAfterTransform(target=esnext).js @@ -67,9 +67,9 @@ function t10() { //// [returnStatementNoAsiAfterTransform.js] function t1() { - return + return ( // comment - a; + (a)); } function t2() { return @@ -102,17 +102,17 @@ function t7() { a ``; } function t8() { - return + return ( // comment - a; + (a)); } function t9() { - return + return ( // comment - a; + (a)); } function t10() { - return + return ( // comment - a; + (a)); } diff --git a/testdata/baselines/reference/submodule/conformance/returnStatementNoAsiAfterTransform(target=esnext).js.diff b/testdata/baselines/reference/submodule/conformance/returnStatementNoAsiAfterTransform(target=esnext).js.diff index b5a0ca9fd6..13cbf1c3ec 100644 --- a/testdata/baselines/reference/submodule/conformance/returnStatementNoAsiAfterTransform(target=esnext).js.diff +++ b/testdata/baselines/reference/submodule/conformance/returnStatementNoAsiAfterTransform(target=esnext).js.diff @@ -1,14 +1,11 @@ --- old.returnStatementNoAsiAfterTransform(target=esnext).js +++ new.returnStatementNoAsiAfterTransform(target=esnext).js -@@= skipped -66, +66 lines =@@ - - //// [returnStatementNoAsiAfterTransform.js] +@@= skipped -68, +68 lines =@@ function t1() { -- return ( -+ return + return ( // comment - a); -+ a; ++ (a)); } function t2() { - return ( @@ -53,23 +50,20 @@ + a ``; } function t8() { -- return ( -+ return + return ( // comment - a); -+ a; ++ (a)); } function t9() { -- return ( -+ return + return ( // comment - a); -+ a; ++ (a)); } function t10() { -- return ( -+ return + return ( // comment - a); -+ a; ++ (a)); } \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/yieldStatementNoAsiAfterTransform(target=es5).js b/testdata/baselines/reference/submodule/conformance/yieldStatementNoAsiAfterTransform(target=es5).js index c0af9e05dd..fee14354e6 100644 --- a/testdata/baselines/reference/submodule/conformance/yieldStatementNoAsiAfterTransform(target=es5).js +++ b/testdata/baselines/reference/submodule/conformance/yieldStatementNoAsiAfterTransform(target=es5).js @@ -67,9 +67,9 @@ function *t10() { //// [yieldStatementNoAsiAfterTransform.js] function* t1() { - yield + yield ( // comment - a; + (a)); } function* t2() { yield @@ -102,17 +102,17 @@ function* t7() { a ``; } function* t8() { - yield + yield ( // comment - a; + (a)); } function* t9() { - yield + yield ( // comment - a; + (a)); } function* t10() { - yield + yield ( // comment - a; + (a)); } diff --git a/testdata/baselines/reference/submodule/conformance/yieldStatementNoAsiAfterTransform(target=es5).js.diff b/testdata/baselines/reference/submodule/conformance/yieldStatementNoAsiAfterTransform(target=es5).js.diff index 3af252235d..f633fcc2cd 100644 --- a/testdata/baselines/reference/submodule/conformance/yieldStatementNoAsiAfterTransform(target=es5).js.diff +++ b/testdata/baselines/reference/submodule/conformance/yieldStatementNoAsiAfterTransform(target=es5).js.diff @@ -155,9 +155,9 @@ - } - }); +function* t1() { -+ yield ++ yield ( + // comment -+ a; ++ (a)); +} +function* t2() { + yield @@ -190,17 +190,17 @@ + a ``; +} +function* t8() { -+ yield ++ yield ( + // comment -+ a; ++ (a)); +} +function* t9() { -+ yield ++ yield ( + // comment -+ a; ++ (a)); +} +function* t10() { -+ yield ++ yield ( + // comment -+ a; ++ (a)); } \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/yieldStatementNoAsiAfterTransform(target=esnext).js b/testdata/baselines/reference/submodule/conformance/yieldStatementNoAsiAfterTransform(target=esnext).js index c0af9e05dd..fee14354e6 100644 --- a/testdata/baselines/reference/submodule/conformance/yieldStatementNoAsiAfterTransform(target=esnext).js +++ b/testdata/baselines/reference/submodule/conformance/yieldStatementNoAsiAfterTransform(target=esnext).js @@ -67,9 +67,9 @@ function *t10() { //// [yieldStatementNoAsiAfterTransform.js] function* t1() { - yield + yield ( // comment - a; + (a)); } function* t2() { yield @@ -102,17 +102,17 @@ function* t7() { a ``; } function* t8() { - yield + yield ( // comment - a; + (a)); } function* t9() { - yield + yield ( // comment - a; + (a)); } function* t10() { - yield + yield ( // comment - a; + (a)); } diff --git a/testdata/baselines/reference/submodule/conformance/yieldStatementNoAsiAfterTransform(target=esnext).js.diff b/testdata/baselines/reference/submodule/conformance/yieldStatementNoAsiAfterTransform(target=esnext).js.diff index 1cd1217449..47e58b4ce6 100644 --- a/testdata/baselines/reference/submodule/conformance/yieldStatementNoAsiAfterTransform(target=esnext).js.diff +++ b/testdata/baselines/reference/submodule/conformance/yieldStatementNoAsiAfterTransform(target=esnext).js.diff @@ -1,14 +1,11 @@ --- old.yieldStatementNoAsiAfterTransform(target=esnext).js +++ new.yieldStatementNoAsiAfterTransform(target=esnext).js -@@= skipped -66, +66 lines =@@ - - //// [yieldStatementNoAsiAfterTransform.js] +@@= skipped -68, +68 lines =@@ function* t1() { -- yield ( -+ yield + yield ( // comment - a); -+ a; ++ (a)); } function* t2() { - yield ( @@ -53,23 +50,20 @@ + a ``; } function* t8() { -- yield ( -+ yield + yield ( // comment - a); -+ a; ++ (a)); } function* t9() { -- yield ( -+ yield + yield ( // comment - a); -+ a; ++ (a)); } function* t10() { -- yield ( -+ yield + yield ( // comment - a); -+ a; ++ (a)); } \ No newline at end of file