Skip to content

Commit 638007b

Browse files
committed
feat(parser): apply preserveParens to TSParenthesizedType (oxc-project#9653)
closes oxc-project#9616
1 parent c174600 commit 638007b

File tree

5 files changed

+35
-10
lines changed

5 files changed

+35
-10
lines changed

crates/oxc_parser/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,15 +199,16 @@ pub struct ParseOptions {
199199
/// [`return`]: oxc_ast::ast::ReturnStatement
200200
pub allow_return_outside_function: bool,
201201

202-
/// Emit [`ParenthesizedExpression`]s in AST.
202+
/// Emit [`ParenthesizedExpression`]s and [`TSParenthesizedType`] in AST.
203203
///
204204
/// If this option is `true`, parenthesized expressions are represented by
205-
/// (non-standard) [`ParenthesizedExpression`] nodes that have a single `expression` property
206-
/// containing the expression inside parentheses.
205+
/// (non-standard) [`ParenthesizedExpression`] and [`TSParenthesizedType`] nodes
206+
/// that have a single `expression` property containing the expression inside parentheses.
207207
///
208208
/// Default: `true`
209209
///
210210
/// [`ParenthesizedExpression`]: oxc_ast::ast::ParenthesizedExpression
211+
/// [`TSParenthesizedType`]: oxc_ast::ast::TSParenthesizedType
211212
pub preserve_parens: bool,
212213

213214
/// Allow V8 runtime calls in the AST.

crates/oxc_parser/src/ts/types.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,11 @@ impl<'a> ParserImpl<'a> {
936936
self.bump_any(); // bump `(`
937937
let ty = self.parse_ts_type()?;
938938
self.expect(Kind::RParen)?;
939-
Ok(self.ast.ts_type_parenthesized_type(self.end_span(span), ty))
939+
Ok(if self.options.preserve_parens {
940+
self.ast.ts_type_parenthesized_type(self.end_span(span), ty)
941+
} else {
942+
ty
943+
})
940944
}
941945

942946
fn parse_literal_type_node(&mut self, negative: bool) -> Result<TSType<'a>> {

napi/parser/index.d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,11 @@ export interface ParserOptions {
151151
*/
152152
astType?: 'js' | 'ts'
153153
/**
154-
* Emit `ParenthesizedExpression` in AST.
154+
* Emit `ParenthesizedExpression` and `TSParenthesizedType` in AST.
155155
*
156156
* If this option is true, parenthesized expressions are represented by
157-
* (non-standard) `ParenthesizedExpression` nodes that have a single `expression` property
158-
* containing the expression inside parentheses.
157+
* (non-standard) `ParenthesizedExpression` and `TSParenthesizedType` nodes that
158+
* have a single `expression` property containing the expression inside parentheses.
159159
*
160160
* @default true
161161
*/

napi/parser/src/types.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ pub struct ParserOptions {
2222
#[napi(ts_type = "'js' | 'ts'")]
2323
pub ast_type: Option<String>,
2424

25-
/// Emit `ParenthesizedExpression` in AST.
25+
/// Emit `ParenthesizedExpression` and `TSParenthesizedType` in AST.
2626
///
2727
/// If this option is true, parenthesized expressions are represented by
28-
/// (non-standard) `ParenthesizedExpression` nodes that have a single `expression` property
29-
/// containing the expression inside parentheses.
28+
/// (non-standard) `ParenthesizedExpression` and `TSParenthesizedType` nodes that
29+
/// have a single `expression` property containing the expression inside parentheses.
3030
///
3131
/// @default true
3232
pub preserve_parens: Option<bool>,

napi/parser/test/parse.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Worker } from 'node:worker_threads';
22
import { describe, expect, it } from 'vitest';
33

44
import { parseAsync, parseSync } from '../index.js';
5+
import type { ExpressionStatement, TSTypeAliasDeclaration } from '../index.js';
56

67
describe('parse', () => {
78
const code = '/* comment */ foo';
@@ -244,6 +245,25 @@ describe('parse', () => {
244245
});
245246
});
246247
});
248+
249+
describe('preserveParens', () => {
250+
it('should include parens when true', () => {
251+
let ret = parseSync('test.js', '(x)');
252+
expect((ret.program.body[0] as ExpressionStatement).expression.type).toBe('ParenthesizedExpression');
253+
254+
ret = parseSync('test.ts', 'type Foo = (x)');
255+
expect((ret.program.body[0] as TSTypeAliasDeclaration).typeAnnotation.type).toBe('TSParenthesizedType');
256+
});
257+
258+
it('should omit parens when false', () => {
259+
const options = { preserveParens: false };
260+
let ret = parseSync('test.js', '(x)', options);
261+
expect((ret.program.body[0] as ExpressionStatement).expression.type).toBe('Identifier');
262+
263+
ret = parseSync('test.ts', 'type Foo = (x)', options);
264+
expect((ret.program.body[0] as TSTypeAliasDeclaration).typeAnnotation.type).toBe('TSTypeReference');
265+
});
266+
});
247267
});
248268

249269
describe('UTF-16 span', () => {

0 commit comments

Comments
 (0)