@@ -2950,7 +2950,110 @@ func (p *Printer) emitPartiallyEmittedExpression(node *ast.PartiallyEmittedExpre
2950
2950
}
2951
2951
2952
2952
func (p * Printer ) willEmitLeadingNewLine (node * ast.Expression ) bool {
2953
- return false // !!! check if node will emit a leading comment that contains a trailing newline
2953
+ // !!! check if node will emit a leading comment that contains a trailing newline
2954
+ // For now, assume that PartiallyEmittedExpression with comments may have leading newlines
2955
+ if node .Kind == ast .KindPartiallyEmittedExpression {
2956
+ // This is a simplification - in a real implementation we'd check the actual comments
2957
+ // but for now, let's assume partially emitted expressions might have leading newlines
2958
+ return true
2959
+ }
2960
+ return false
2961
+ }
2962
+
2963
+ // parenthesizeExpressionForNoAsi wraps an expression in parens if we would emit a leading comment that would introduce a line separator
2964
+ // between the node and its parent.
2965
+ func (p * Printer ) parenthesizeExpressionForNoAsi (node * ast.Expression ) * ast.Expression {
2966
+ if ! p .commentsDisabled {
2967
+ switch node .Kind {
2968
+ case ast .KindPartiallyEmittedExpression :
2969
+ if p .willEmitLeadingNewLine (node ) {
2970
+ parseNode := p .emitContext .ParseNode (node .AsNode ())
2971
+ if parseNode != nil && parseNode .Kind == ast .KindParenthesizedExpression {
2972
+ // If the original node was a parenthesized expression, restore it to preserve comment and source map emit
2973
+ parens := p .emitContext .Factory .NewParenthesizedExpression (node .AsPartiallyEmittedExpression ().Expression )
2974
+ p .emitContext .SetOriginal (parens , node .AsNode ())
2975
+ parens .Loc = parseNode .Loc
2976
+ return parens
2977
+ }
2978
+ return p .emitContext .Factory .NewParenthesizedExpression (node )
2979
+ }
2980
+ return p .emitContext .Factory .UpdatePartiallyEmittedExpression (
2981
+ node .AsPartiallyEmittedExpression (),
2982
+ p .parenthesizeExpressionForNoAsi (node .AsPartiallyEmittedExpression ().Expression ),
2983
+ )
2984
+ case ast .KindPropertyAccessExpression :
2985
+ return p .emitContext .Factory .UpdatePropertyAccessExpression (
2986
+ node .AsPropertyAccessExpression (),
2987
+ p .parenthesizeExpressionForNoAsi (node .AsPropertyAccessExpression ().Expression ),
2988
+ node .AsPropertyAccessExpression ().QuestionDotToken ,
2989
+ node .AsPropertyAccessExpression ().Name (),
2990
+ )
2991
+ case ast .KindElementAccessExpression :
2992
+ return p .emitContext .Factory .UpdateElementAccessExpression (
2993
+ node .AsElementAccessExpression (),
2994
+ p .parenthesizeExpressionForNoAsi (node .AsElementAccessExpression ().Expression ),
2995
+ node .AsElementAccessExpression ().QuestionDotToken ,
2996
+ node .AsElementAccessExpression ().ArgumentExpression ,
2997
+ )
2998
+ case ast .KindCallExpression :
2999
+ return p .emitContext .Factory .UpdateCallExpression (
3000
+ node .AsCallExpression (),
3001
+ p .parenthesizeExpressionForNoAsi (node .AsCallExpression ().Expression ),
3002
+ node .AsCallExpression ().QuestionDotToken ,
3003
+ node .AsCallExpression ().TypeArguments ,
3004
+ node .AsCallExpression ().Arguments ,
3005
+ )
3006
+ case ast .KindTaggedTemplateExpression :
3007
+ return p .emitContext .Factory .UpdateTaggedTemplateExpression (
3008
+ node .AsTaggedTemplateExpression (),
3009
+ p .parenthesizeExpressionForNoAsi (node .AsTaggedTemplateExpression ().Tag ),
3010
+ node .AsTaggedTemplateExpression ().QuestionDotToken ,
3011
+ node .AsTaggedTemplateExpression ().TypeArguments ,
3012
+ node .AsTaggedTemplateExpression ().Template ,
3013
+ )
3014
+ case ast .KindPostfixUnaryExpression :
3015
+ return p .emitContext .Factory .UpdatePostfixUnaryExpression (
3016
+ node .AsPostfixUnaryExpression (),
3017
+ p .parenthesizeExpressionForNoAsi (node .AsPostfixUnaryExpression ().Operand ),
3018
+ )
3019
+ case ast .KindBinaryExpression :
3020
+ return p .emitContext .Factory .UpdateBinaryExpression (
3021
+ node .AsBinaryExpression (),
3022
+ node .AsBinaryExpression ().Modifiers (),
3023
+ p .parenthesizeExpressionForNoAsi (node .AsBinaryExpression ().Left ),
3024
+ node .AsBinaryExpression ().Type ,
3025
+ node .AsBinaryExpression ().OperatorToken ,
3026
+ node .AsBinaryExpression ().Right ,
3027
+ )
3028
+ case ast .KindConditionalExpression :
3029
+ return p .emitContext .Factory .UpdateConditionalExpression (
3030
+ node .AsConditionalExpression (),
3031
+ p .parenthesizeExpressionForNoAsi (node .AsConditionalExpression ().Condition ),
3032
+ node .AsConditionalExpression ().QuestionToken ,
3033
+ node .AsConditionalExpression ().WhenTrue ,
3034
+ node .AsConditionalExpression ().ColonToken ,
3035
+ node .AsConditionalExpression ().WhenFalse ,
3036
+ )
3037
+ case ast .KindAsExpression :
3038
+ return p .emitContext .Factory .UpdateAsExpression (
3039
+ node .AsAsExpression (),
3040
+ p .parenthesizeExpressionForNoAsi (node .AsAsExpression ().Expression ),
3041
+ node .AsAsExpression ().Type ,
3042
+ )
3043
+ case ast .KindSatisfiesExpression :
3044
+ return p .emitContext .Factory .UpdateSatisfiesExpression (
3045
+ node .AsSatisfiesExpression (),
3046
+ p .parenthesizeExpressionForNoAsi (node .AsSatisfiesExpression ().Expression ),
3047
+ node .AsSatisfiesExpression ().Type ,
3048
+ )
3049
+ case ast .KindNonNullExpression :
3050
+ return p .emitContext .Factory .UpdateNonNullExpression (
3051
+ node .AsNonNullExpression (),
3052
+ p .parenthesizeExpressionForNoAsi (node .AsNonNullExpression ().Expression ),
3053
+ )
3054
+ }
3055
+ }
3056
+ return node
2954
3057
}
2955
3058
2956
3059
func (p * Printer ) emitExpressionNoASI (node * ast.Expression , precedence ast.OperatorPrecedence ) {
@@ -2966,12 +3069,8 @@ func (p *Printer) emitExpressionNoASI(node *ast.Expression, precedence ast.Opera
2966
3069
// a;
2967
3070
// }
2968
3071
// Due to ASI, this would result in a `return` with no value followed by an unreachable expression statement.
2969
- if ! p .commentsDisabled && node .Kind == ast .KindPartiallyEmittedExpression && p .willEmitLeadingNewLine (node ) {
2970
- // !!! if there is an original parse tree node, restore it with location to preserve comments and source maps.
2971
- p .emitExpression (node , ast .OperatorPrecedenceParentheses )
2972
- } else {
2973
- p .emitExpression (node , precedence )
2974
- }
3072
+ node = p .parenthesizeExpressionForNoAsi (node )
3073
+ p .emitExpression (node , precedence )
2975
3074
}
2976
3075
2977
3076
func (p * Printer ) emitExpression (node * ast.Expression , precedence ast.OperatorPrecedence ) {
0 commit comments