@@ -43,10 +43,31 @@ function postprocess(ast, options) {
4343
4444 mergeNestledJsdocComments ( comments ) ;
4545
46+ // `InterpreterDirective` from babel parser and flow parser
47+ // Other parsers parse it as comment, babel treat it as comment too
48+ // https://github.com/babel/babel/issues/15116
49+ const program = ast . type === "File" ? ast . program : ast ;
50+ if ( program . interpreter ) {
51+ comments . unshift ( program . interpreter ) ;
52+ delete program . interpreter ;
53+ }
54+
55+ if ( isOxcTs && ast . hashbang ) {
56+ comments . unshift ( ast . hashbang ) ;
57+ delete ast . hashbang ;
58+ }
59+
60+ // In `typescript` and `flow`, `Program` doesn't count whitespace and comments
61+ // See https://github.com/typescript-eslint/typescript-eslint/issues/11026
62+ // See https://github.com/facebook/flow/issues/8537
63+ if ( ast . type === "Program" ) {
64+ ast . range = [ 0 , text . length ] ;
65+ }
66+
4667 let typeCastCommentsEnds ;
4768
4869 ast = visitNode ( ast , {
49- onLeave ( node ) {
70+ onEnter ( node ) {
5071 switch ( node . type ) {
5172 case "ParenthesizedExpression" : {
5273 const { expression } = node ;
@@ -58,7 +79,7 @@ function postprocess(ast, options) {
5879 return expression ;
5980 }
6081
61- let keepTypeCast = false ;
82+ let shouldKeepParenthesizedExpression = false ;
6283 if ( ! isOxcTs ) {
6384 if ( ! typeCastCommentsEnds ) {
6485 typeCastCommentsEnds = [ ] ;
@@ -74,27 +95,21 @@ function postprocess(ast, options) {
7495 const previousCommentEnd = typeCastCommentsEnds . findLast (
7596 ( end ) => end <= start ,
7697 ) ;
77- keepTypeCast =
98+ shouldKeepParenthesizedExpression =
7899 previousCommentEnd &&
79100 // check that there are only white spaces between the comment and the parenthesis
80101 text . slice ( previousCommentEnd , start ) . trim ( ) . length === 0 ;
81102 }
82103
83- if ( ! keepTypeCast ) {
84- expression . extra = { ...expression . extra , parenthesized : true } ;
85- return expression ;
104+ if ( shouldKeepParenthesizedExpression ) {
105+ return ;
86106 }
87- break ;
88- }
89107
90- case "LogicalExpression" :
91- // We remove unneeded parens around same-operator LogicalExpressions
92- if ( isUnbalancedLogicalTree ( node ) ) {
93- return rebalanceLogicalTree ( node ) ;
94- }
95- break ;
108+ expression . extra = { ...expression . extra , parenthesized : true } ;
109+ return expression ;
110+ }
96111
97- // This happens when use `oxc-parser` to parse `` `${foo satisfies bar}`; ``
112+ // This happened when use `oxc-parser` to parse `` `${foo satisfies bar}`; ``
98113 // https://github.com/oxc-project/oxc/issues/11313
99114 case "TemplateLiteral" :
100115 /* c8 ignore next 3 */
@@ -128,16 +143,15 @@ function postprocess(ast, options) {
128143 }
129144 break ;
130145 }
146+
131147 // remove redundant TypeScript nodes
132148 case "TSParenthesizedType" :
133149 return node . typeAnnotation ;
134150
135151 // For hack-style pipeline
136152 case "TopicReference" :
137153 ast . extra = { ...ast . extra , __isUsingHackPipeline : true } ;
138- break ;
139-
140- // In Flow parser, it doesn't generate union/intersection types for single type
154+ break ; // In Flow parser, it doesn't generate union/intersection types for single type
141155 case "TSUnionType" :
142156 case "TSIntersectionType" :
143157 if ( node . types . length === 1 ) {
@@ -151,9 +165,21 @@ function postprocess(ast, options) {
151165 node . options = node . attributes ;
152166 }
153167 break ;
168+ }
169+ } ,
170+ onLeave ( node ) {
171+ switch ( node . type ) {
172+ // Children can be parenthesized, need do this in `onLeave`
173+ case "LogicalExpression" :
174+ // We remove unneeded parens around same-operator LogicalExpressions
175+ if ( isUnbalancedLogicalTree ( node ) ) {
176+ return rebalanceLogicalTree ( node ) ;
177+ }
178+ break ;
154179
155180 // https://github.com/babel/babel/issues/17506
156181 // https://github.com/oxc-project/oxc/issues/16074
182+ // It's possible to have parenthesized `argument`, need do this in `onLeave`
157183 case "TSImportType" :
158184 if ( ! node . source && node . argument . type === "TSLiteralType" ) {
159185 node . source = node . argument . literal ;
@@ -169,31 +195,10 @@ function postprocess(ast, options) {
169195 } ,
170196 } ) ;
171197
172- // `InterpreterDirective` from babel parser and flow parser
173- // Other parsers parse it as comment, babel treat it as comment too
174- // https://github.com/babel/babel/issues/15116
175- const program = ast . type === "File" ? ast . program : ast ;
176- if ( program . interpreter ) {
177- comments . unshift ( program . interpreter ) ;
178- delete program . interpreter ;
179- }
180-
181- if ( isOxcTs && ast . hashbang ) {
182- comments . unshift ( ast . hashbang ) ;
183- delete ast . hashbang ;
184- }
185-
186198 /* c8 ignore next 3 */
187199 if ( process . env . NODE_ENV !== "production" ) {
188200 assertComments ( comments , text ) ;
189201 }
190-
191- // In `typescript` and `flow`, `Program` doesn't count whitespace and comments
192- // See https://github.com/typescript-eslint/typescript-eslint/issues/11026
193- // See https://github.com/facebook/flow/issues/8537
194- if ( ast . type === "Program" ) {
195- ast . range = [ 0 , text . length ] ;
196- }
197202 return ast ;
198203}
199204
0 commit comments