Skip to content

Commit cd2dad0

Browse files
Copilotandrewbranch
andcommitted
Implement faithful port of willEmitLeadingNewLine from TypeScript PR #60304
Co-authored-by: andrewbranch <3277153+andrewbranch@users.noreply.github.com>
1 parent 05d960e commit cd2dad0

15 files changed

+172
-1053
lines changed

for grouping

Lines changed: 0 additions & 618 deletions
This file was deleted.

internal/printer/printer.go

Lines changed: 42 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2949,77 +2949,56 @@ func (p *Printer) emitPartiallyEmittedExpression(node *ast.PartiallyEmittedExpre
29492949
}
29502950
}
29512951

2952+
func (p *Printer) commentWillEmitNewLine(comment ast.CommentRange) bool {
2953+
return comment.Kind == ast.KindSingleLineCommentTrivia || comment.HasTrailingNewLine
2954+
}
2955+
29522956
func (p *Printer) willEmitLeadingNewLine(node *ast.Expression) bool {
2953-
// Check if node will emit a leading comment that contains a trailing newline
2954-
if p.commentsDisabled || p.currentSourceFile == nil {
2957+
if p.currentSourceFile == nil {
29552958
return false
29562959
}
2957-
2960+
2961+
text := p.currentSourceFile.Text()
29582962
pos := node.Pos()
2959-
if ast.PositionIsSynthesized(pos) || pos == p.containerPos {
2960-
return false
2963+
2964+
// Get leading comment ranges
2965+
var leadingCommentRanges []ast.CommentRange
2966+
for commentRange := range scanner.GetLeadingCommentRanges(p.emitContext.Factory.AsNodeFactory(), text, pos) {
2967+
leadingCommentRanges = append(leadingCommentRanges, commentRange)
2968+
}
2969+
2970+
if len(leadingCommentRanges) > 0 {
2971+
parseNode := p.emitContext.ParseNode(node.AsNode())
2972+
if parseNode != nil && parseNode.Parent != nil && ast.IsParenthesizedExpression(parseNode.Parent) {
2973+
return true
2974+
}
29612975
}
2962-
2963-
// Get leading comments for this node
2964-
text := p.currentSourceFile.Text()
2965-
hasLeadingNewLineComment := false
2966-
for comment := range scanner.GetLeadingCommentRanges(p.emitContext.Factory.AsNodeFactory(), text, pos) {
2967-
if p.shouldWriteComment(comment) {
2968-
// Check if this comment will cause a newline to be emitted
2969-
if comment.Kind == ast.KindSingleLineCommentTrivia {
2970-
// Single line comments always end with a newline
2971-
hasLeadingNewLineComment = true
2972-
break
2973-
} else if comment.Kind == ast.KindMultiLineCommentTrivia {
2974-
// Multi-line comments may contain newlines or cause newlines
2975-
commentText := text[comment.Pos():comment.End()]
2976-
// Check if the comment ends with a newline or contains newlines
2977-
if len(commentText) > 0 && (commentText[len(commentText)-1] == '\n' || commentText[len(commentText)-1] == '\r') {
2978-
hasLeadingNewLineComment = true
2979-
break
2980-
}
2981-
// Also check if the comment contains internal newlines
2982-
for i := 0; i < len(commentText); i++ {
2983-
if commentText[i] == '\n' || commentText[i] == '\r' {
2984-
hasLeadingNewLineComment = true
2985-
break
2986-
}
2987-
}
2988-
}
2976+
2977+
// Check if any leading comment will emit a newline
2978+
for _, comment := range leadingCommentRanges {
2979+
if p.commentWillEmitNewLine(comment) {
2980+
return true
29892981
}
29902982
}
2991-
2992-
// If this node doesn't have leading comments, check if any of its child expressions do
2993-
if !hasLeadingNewLineComment {
2994-
switch node.Kind {
2995-
case ast.KindAsExpression:
2996-
return p.willEmitLeadingNewLine(node.AsAsExpression().Expression)
2997-
case ast.KindSatisfiesExpression:
2998-
return p.willEmitLeadingNewLine(node.AsSatisfiesExpression().Expression)
2999-
case ast.KindNonNullExpression:
3000-
return p.willEmitLeadingNewLine(node.AsNonNullExpression().Expression)
3001-
case ast.KindParenthesizedExpression:
3002-
return p.willEmitLeadingNewLine(node.AsParenthesizedExpression().Expression)
3003-
case ast.KindPropertyAccessExpression:
3004-
return p.willEmitLeadingNewLine(node.AsPropertyAccessExpression().Expression)
3005-
case ast.KindElementAccessExpression:
3006-
return p.willEmitLeadingNewLine(node.AsElementAccessExpression().Expression)
3007-
case ast.KindCallExpression:
3008-
return p.willEmitLeadingNewLine(node.AsCallExpression().Expression)
3009-
case ast.KindTaggedTemplateExpression:
3010-
return p.willEmitLeadingNewLine(node.AsTaggedTemplateExpression().Tag)
3011-
case ast.KindPostfixUnaryExpression:
3012-
return p.willEmitLeadingNewLine(node.AsPostfixUnaryExpression().Operand)
3013-
case ast.KindBinaryExpression:
3014-
return p.willEmitLeadingNewLine(node.AsBinaryExpression().Left)
3015-
case ast.KindConditionalExpression:
3016-
return p.willEmitLeadingNewLine(node.AsConditionalExpression().Condition)
3017-
case ast.KindPartiallyEmittedExpression:
3018-
return p.willEmitLeadingNewLine(node.AsPartiallyEmittedExpression().Expression)
2983+
2984+
// Check synthetic leading comments (currently stubbed out in this codebase)
2985+
// if some(getSyntheticLeadingComments(node), commentWillEmitNewLine)) return true;
2986+
2987+
// Handle PartiallyEmittedExpression recursively
2988+
if node.Kind == ast.KindPartiallyEmittedExpression {
2989+
partiallyEmitted := node.AsPartiallyEmittedExpression()
2990+
if node.Pos() != partiallyEmitted.Expression.Pos() {
2991+
// Check trailing comments at the expression position
2992+
for trailingComment := range scanner.GetTrailingCommentRanges(p.emitContext.Factory.AsNodeFactory(), text, partiallyEmitted.Expression.Pos()) {
2993+
if p.commentWillEmitNewLine(trailingComment) {
2994+
return true
2995+
}
2996+
}
30192997
}
2998+
return p.willEmitLeadingNewLine(partiallyEmitted.Expression)
30202999
}
3021-
3022-
return hasLeadingNewLineComment
3000+
3001+
return false
30233002
}
30243003

30253004
func (p *Printer) emitExpressionNoASI(node *ast.Expression, precedence ast.OperatorPrecedence) {
@@ -3035,7 +3014,7 @@ func (p *Printer) emitExpressionNoASI(node *ast.Expression, precedence ast.Opera
30353014
// a;
30363015
// }
30373016
// Due to ASI, this would result in a `return` with no value followed by an unreachable expression statement.
3038-
if !p.commentsDisabled && p.willEmitLeadingNewLine(node) {
3017+
if !p.commentsDisabled && node.Kind == ast.KindPartiallyEmittedExpression && p.willEmitLeadingNewLine(node) {
30393018
// !!! if there is an original parse tree node, restore it with location to preserve comments and source maps.
30403019
p.emitExpression(node, ast.OperatorPrecedenceParentheses)
30413020
} else {

tdout on a dedicated line

Lines changed: 0 additions & 258 deletions
This file was deleted.

testdata/baselines/reference/submodule/compiler/commentEmitOnParenthesizedAssertionInReturnStatement.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ export class Foo {
2121
getThing: () => Promise.resolve('')
2222
};
2323
foo() {
24-
return
25-
/* TODO: Avoid using type assertions, please refactor. */ this.client
26-
.getThing();
24+
return (
25+
/* TODO: Avoid using type assertions, please refactor. */ (this.client
26+
.getThing()));
2727
}
2828
}

0 commit comments

Comments
 (0)