Skip to content

Commit 4eb0da8

Browse files
committed
feat(napi/parser): raw transfer support range field
1 parent 85948c9 commit 4eb0da8

File tree

15 files changed

+12918
-818
lines changed

15 files changed

+12918
-818
lines changed

.github/generated/ast_changes_watch_list.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ src:
6868
- 'crates/oxc_traverse/src/generated/scopes_collector.rs'
6969
- 'napi/parser/generated/constants.js'
7070
- 'napi/parser/generated/deserialize/js.js'
71+
- 'napi/parser/generated/deserialize/js_range.js'
7172
- 'napi/parser/generated/deserialize/ts.js'
73+
- 'napi/parser/generated/deserialize/ts_range.js'
7274
- 'napi/parser/generated/lazy/constructors.js'
7375
- 'napi/parser/generated/lazy/types.js'
7476
- 'napi/parser/generated/lazy/walk.js'

crates/oxc_ast/src/serialize/js.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ impl ESTree for CatchParameterConverter<'_, '_> {
119119
const params = DESER[Vec<FormalParameter>](POS_OFFSET.items);
120120
if (uint32[(POS_OFFSET.rest) >> 2] !== 0 && uint32[(POS_OFFSET.rest + 4) >> 2] !== 0) {
121121
pos = uint32[(POS_OFFSET.rest) >> 2];
122+
let start, end;
122123
params.push({
123124
type: 'RestElement',
124125
...(IS_TS && { decorators: [] }),
@@ -130,8 +131,9 @@ impl ESTree for CatchParameterConverter<'_, '_> {
130131
),
131132
value: null,
132133
}),
133-
start: DESER[u32]( POS_OFFSET<BindingRestElement>.span.start ),
134-
end: DESER[u32]( POS_OFFSET<BindingRestElement>.span.end ),
134+
start: start = DESER[u32]( POS_OFFSET<BindingRestElement>.span.start ),
135+
end: end = DESER[u32]( POS_OFFSET<BindingRestElement>.span.end ),
136+
...(RANGE && { range: [start, end] }),
135137
});
136138
}
137139
params
@@ -192,6 +194,7 @@ impl ESTree for FormalParametersRest<'_, '_> {
192194
param.optional = DESER[bool](POS_OFFSET.pattern.optional);
193195
param.typeAnnotation = DESER[Option<Box<TSTypeAnnotation>>](POS_OFFSET.pattern.type_annotation);
194196
} else {
197+
let start, end;
195198
param = {
196199
type: 'TSParameterProperty',
197200
accessibility,
@@ -200,8 +203,9 @@ impl ESTree for FormalParametersRest<'_, '_> {
200203
parameter: DESER[BindingPattern](POS_OFFSET.pattern),
201204
readonly,
202205
static: false,
203-
start: DESER[u32]( POS_OFFSET<BindingRestElement>.span.start ),
204-
end: DESER[u32]( POS_OFFSET<BindingRestElement>.span.end ),
206+
start: start = DESER[u32]( POS_OFFSET<BindingRestElement>.span.start ),
207+
end: end = DESER[u32]( POS_OFFSET<BindingRestElement>.span.end ),
208+
...(RANGE && { range: [start, end] }),
205209
};
206210
}
207211
} else {
@@ -416,6 +420,7 @@ impl ESTree for ArrowFunctionExpressionBody<'_> {
416420
}),
417421
start: THIS.start,
418422
end: THIS.end,
423+
...(RANGE && { range: [THIS.start, THIS.end] }),
419424
};
420425
value
421426
"
@@ -455,11 +460,13 @@ impl ESTree for AssignmentTargetPropertyIdentifierInit<'_> {
455460
#[estree(raw_deser = "
456461
let node = DESER[Expression](POS_OFFSET.expression);
457462
if (preserveParens) {
463+
let start, end;
458464
node = {
459465
type: 'ParenthesizedExpression',
460466
expression: node,
461-
start: DESER[u32]( POS_OFFSET.span.start ),
462-
end: DESER[u32]( POS_OFFSET.span.end ),
467+
start: start = DESER[u32]( POS_OFFSET.span.start ),
468+
end: end = DESER[u32]( POS_OFFSET.span.end ),
469+
...(RANGE && { range: [start, end] }),
463470
};
464471
}
465472
node

crates/oxc_ast/src/serialize/jsx.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl ESTree for JSXOpeningElementSelfClosing<'_, '_> {
5656
ts_type = "JSXIdentifier",
5757
raw_deser = "
5858
const ident = DESER[Box<IdentifierReference>](POS);
59-
{ type: 'JSXIdentifier', name: ident.name, start: ident.start, end: ident.end }
59+
{ type: 'JSXIdentifier', name: ident.name, start: ident.start, end: ident.end, ...(RANGE && { range: ident.range }) }
6060
"
6161
)]
6262
pub struct JSXElementIdentifierReference<'a, 'b>(pub &'b IdentifierReference<'a>);
@@ -75,7 +75,7 @@ impl ESTree for JSXElementIdentifierReference<'_, '_> {
7575
ts_type = "JSXIdentifier",
7676
raw_deser = "
7777
const thisExpr = DESER[Box<ThisExpression>](POS);
78-
{ type: 'JSXIdentifier', name: 'this', start: thisExpr.start, end: thisExpr.end }
78+
{ type: 'JSXIdentifier', name: 'this', start: thisExpr.start, end: thisExpr.end, ...(RANGE && { range: thisExpr.range }) }
7979
"
8080
)]
8181
pub struct JSXElementThisExpression<'b>(pub &'b ThisExpression);

crates/oxc_ast/src/serialize/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ impl Program<'_> {
155155
hashbang: DESER[Option<Hashbang>](POS_OFFSET.hashbang),
156156
start,
157157
end,
158+
...(RANGE && { range: [start, end] }),
158159
};
159160
program
160161
")]

crates/oxc_ast/src/serialize/ts.rs

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,27 +60,36 @@ impl ESTree for ExpressionStatementDirective<'_, '_> {
6060
if (body !== null && body.type === 'TSModuleDeclaration') {
6161
let innerId = body.id;
6262
if (innerId.type === 'Identifier') {
63+
let start, end;
6364
id = {
6465
type: 'TSQualifiedName',
6566
left: id,
6667
right: innerId,
67-
start: id.start,
68-
end: innerId.end,
68+
start: start = id.start,
69+
end: end = innerId.end,
70+
...(RANGE && { range: [start, end] }),
6971
};
7072
} else {
7173
// Replace `left` of innermost `TSQualifiedName` with a nested `TSQualifiedName` with `id` of
7274
// this module on left, and previous `left` of innermost `TSQualifiedName` on right
7375
while (true) {
74-
innerId.start = id.start;
76+
if (RANGE) {
77+
innerId.start = innerId.range[0] = id.start;
78+
} else {
79+
innerId.start = id.start;
80+
}
7581
if (innerId.left.type === 'Identifier') break;
7682
innerId = innerId.left;
7783
}
84+
85+
let start, end;
7886
innerId.left = {
7987
type: 'TSQualifiedName',
8088
left: id,
8189
right: innerId.left,
82-
start: id.start,
83-
end: innerId.left.end,
90+
start: start = id.start,
91+
end: end = innerId.left.end,
92+
...(RANGE && { range: [start, end] }),
8493
};
8594
id = body.id;
8695
}
@@ -89,8 +98,18 @@ impl ESTree for ExpressionStatementDirective<'_, '_> {
8998
9099
// Skip `body` field if `null`
91100
const node = body === null
92-
? { type: 'TSModuleDeclaration', id, kind, declare, global, start, end }
93-
: { type: 'TSModuleDeclaration', id, body, kind, declare, global, start, end };
101+
? {
102+
type: 'TSModuleDeclaration',
103+
id, kind, declare, global,
104+
start, end,
105+
...(RANGE && { range: [start, end] })
106+
}
107+
: {
108+
type: 'TSModuleDeclaration',
109+
id, body, kind, declare, global,
110+
start, end,
111+
...(RANGE && { range: [start, end] })
112+
};
94113
node
95114
")]
96115
pub struct TSModuleDeclarationConverter<'a, 'b>(pub &'b TSModuleDeclaration<'a>);
@@ -273,26 +292,30 @@ impl ESTree for TSMappedTypeConstraint<'_, '_> {
273292
let expression = DESER[TSTypeName](POS_OFFSET.expression);
274293
if (expression.type === 'TSQualifiedName') {
275294
let object = expression.left;
295+
let start, end;
276296
let parent = expression = {
277297
type: 'MemberExpression',
278298
object,
279299
property: expression.right,
280300
optional: false,
281301
computed: false,
282-
start: expression.start,
283-
end: expression.end,
302+
start: start = expression.start,
303+
end: end = expression.end,
304+
...(RANGE && { range: [start, end] }),
284305
};
285306
286307
while (object.type === 'TSQualifiedName') {
287308
const { left } = object;
309+
let start, end;
288310
parent = parent.object = {
289311
type: 'MemberExpression',
290312
object: left,
291313
property: object.right,
292314
optional: false,
293315
computed: false,
294-
start: object.start,
295-
end: object.end,
316+
start: start = object.start,
317+
end: end = object.end,
318+
...(RANGE && { range: [start, end] }),
296319
};
297320
object = left;
298321
}
@@ -415,11 +438,13 @@ impl ESTree for TSFunctionTypeParams<'_, '_> {
415438
#[estree(raw_deser = "
416439
let node = DESER[TSType](POS_OFFSET.type_annotation);
417440
if (preserveParens) {
441+
let start, end;
418442
node = {
419443
type: 'TSParenthesizedType',
420444
typeAnnotation: node,
421-
start: DESER[u32]( POS_OFFSET.span.start ),
422-
end: DESER[u32]( POS_OFFSET.span.end ),
445+
start: start = DESER[u32]( POS_OFFSET.span.start ),
446+
end: end = DESER[u32]( POS_OFFSET.span.end ),
447+
...(RANGE && { range: [start, end] }),
423448
};
424449
}
425450
node

crates/oxc_syntax/src/serialize.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ macro_rules! dummy_estree_impl {
2525
ts_type = "Dummy",
2626
raw_deser = "
2727
var nameSpan = DESER[NameSpan](POS);
28-
{kind: 'Name', name: nameSpan.value, start: nameSpan.start, end: nameSpan.end}
28+
{ kind: 'Name', name: nameSpan.value, start: nameSpan.start, end: nameSpan.end, ...(RANGE && { range: nameSpan.range }) }
2929
"
3030
)]
3131
pub struct ImportOrExportNameName<'a, 'b>(#[expect(dead_code)] pub &'b NameSpan<'a>);
@@ -38,7 +38,7 @@ dummy_estree_impl!(ImportOrExportNameName<'_, '_>);
3838
ts_type = "Dummy",
3939
raw_deser = "
4040
var nameSpan = DESER[NameSpan](POS);
41-
{kind: 'Default', name: nameSpan.value, start: nameSpan.start, end: nameSpan.end}
41+
{ kind: 'Default', name: nameSpan.value, start: nameSpan.start, end: nameSpan.end, ...(RANGE && { range: nameSpan.range }) }
4242
"
4343
)]
4444
pub struct ExportLocalNameDefault<'a, 'b>(#[expect(dead_code)] pub &'b NameSpan<'a>);
@@ -47,7 +47,10 @@ dummy_estree_impl!(ExportLocalNameDefault<'_, '_>);
4747

4848
/// Serializer for `Null` variant of `ExportLocalName`, `ExportExportName`, and `ExportImportName`.
4949
#[ast_meta]
50-
#[estree(ts_type = "Dummy", raw_deser = "{kind: 'None', name: null, start: null, end: null}")]
50+
#[estree(
51+
ts_type = "Dummy",
52+
raw_deser = "{ kind: 'None', name: null, start: null, end: null, ...(RANGE && { range: [null, null] }) }"
53+
)]
5154
pub struct ExportNameNull(pub ());
5255

5356
dummy_estree_impl!(ExportNameNull);
@@ -57,8 +60,8 @@ dummy_estree_impl!(ExportNameNull);
5760
#[estree(
5861
ts_type = "Dummy",
5962
raw_deser = "
60-
var span = DESER[Span](POS);
61-
{kind: 'Default', name: null, start: span.start, end: span.end}
63+
var { start, end } = DESER[Span](POS);
64+
{ kind: 'Default', name: null, start, end, ...(RANGE && { range: [start, end] }) }
6265
"
6366
)]
6467
pub struct ImportOrExportNameDefault<'b>(#[expect(dead_code)] pub &'b Span);
@@ -67,7 +70,10 @@ dummy_estree_impl!(ImportOrExportNameDefault<'_>);
6770

6871
/// Serializer for `All` variant of `ExportImportName`.
6972
#[ast_meta]
70-
#[estree(ts_type = "Dummy", raw_deser = "{kind: 'All', name: null, start: null, end: null}")]
73+
#[estree(
74+
ts_type = "Dummy",
75+
raw_deser = "{ kind: 'All', name: null, start: null, end: null, ...(RANGE && { range: [null, null] }) }"
76+
)]
7177
pub struct ExportImportNameAll(pub ());
7278

7379
dummy_estree_impl!(ExportImportNameAll);
@@ -76,7 +82,7 @@ dummy_estree_impl!(ExportImportNameAll);
7682
#[ast_meta]
7783
#[estree(
7884
ts_type = "Dummy",
79-
raw_deser = "{kind: 'AllButDefault', name: null, start: null, end: null}"
85+
raw_deser = "{ kind: 'AllButDefault', name: null, start: null, end: null, ...(RANGE && { range: [null, null] }) }"
8086
)]
8187
pub struct ExportImportNameAllButDefault(pub ());
8288

@@ -86,7 +92,7 @@ dummy_estree_impl!(ExportImportNameAllButDefault);
8692
#[ast_meta]
8793
#[estree(
8894
ts_type = "Dummy",
89-
raw_deser = "{kind: 'NamespaceObject', name: null, start: null, end: null}"
95+
raw_deser = "{ kind: 'NamespaceObject', name: null, start: null, end: null, ...(RANGE && { range: [null, null] }) }"
9096
)]
9197
pub struct ImportImportNameNamespaceObject(pub ());
9298

0 commit comments

Comments
 (0)