Skip to content

Commit c2c0268

Browse files
committed
feat(syntax): introduce CommentNodeId (#11214)
First step towards #11213. Introduce `CommentNodeId`, which we'll add to AST structs. Note: `CommentNodeId` wraps a `u32`, not a `NonMaxU32`. `CommentNodeId`s will be created in parser, every node will have one, and they will never change thereafter. So we don't need to wrap in `Cell<Option<CommentNodeId>>`, the way we do with e.g. `ScopeId`. So `NonMaxU32` offers no benefit here, and would be slightly more costly. Add a method `get_comment_node_id` to `AstBuilder` which other `AstBuilder` methods will call to populate a field with a `CommentNodeId` field. This method is currently a dummy. `CommentNodeId` is marked `#[clone_in(default)]`, `#[content_eq(skip)]`, `#[estree(skip)]`, so adding this field to AST types will not disrupt any other code.
1 parent c16ea02 commit c2c0268

File tree

13 files changed

+422
-274
lines changed

13 files changed

+422
-274
lines changed

.github/generated/ast_changes_watch_list.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ src:
4343
- 'crates/oxc_span/src/generated/derive_estree.rs'
4444
- 'crates/oxc_span/src/source_type.rs'
4545
- 'crates/oxc_span/src/span.rs'
46+
- 'crates/oxc_syntax/src/comment_node.rs'
4647
- 'crates/oxc_syntax/src/generated/assert_layouts.rs'
4748
- 'crates/oxc_syntax/src/generated/derive_clone_in.rs'
4849
- 'crates/oxc_syntax/src/generated/derive_content_eq.rs'

crates/oxc_ast/src/ast_builder_impl.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use std::borrow::Cow;
44

55
use oxc_allocator::{Allocator, AllocatorAccessor, Box, FromIn, IntoIn, Vec};
66
use oxc_span::{Atom, SPAN, Span};
7-
use oxc_syntax::{number::NumberBase, operator::UnaryOperator, scope::ScopeId};
7+
use oxc_syntax::{
8+
comment_node::CommentNodeId, number::NumberBase, operator::UnaryOperator, scope::ScopeId,
9+
};
810

911
use crate::{AstBuilder, ast::*};
1012

@@ -33,6 +35,13 @@ impl<'a> AstBuilder<'a> {
3335
Self { allocator }
3436
}
3537

38+
/// Create [`CommentNodeId`] for an AST node.
39+
#[expect(dead_code, clippy::unused_self, clippy::trivially_copy_pass_by_ref)]
40+
pub(crate) fn get_comment_node_id(&self) -> CommentNodeId {
41+
// TODO: Generate a real ID
42+
CommentNodeId::DUMMY
43+
}
44+
3645
/// Move a value into the memory arena.
3746
#[inline]
3847
pub fn alloc<T>(self, value: T) -> Box<'a, T> {

crates/oxc_ast/src/generated/ast_builder.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
//! AST node factories
55
6+
#![allow(unused_imports)]
67
#![expect(
78
clippy::default_trait_access,
89
clippy::inconsistent_struct_constructor,
@@ -12,7 +13,9 @@
1213
use std::cell::Cell;
1314

1415
use oxc_allocator::{Allocator, Box, IntoIn, Vec};
15-
use oxc_syntax::{reference::ReferenceId, scope::ScopeId, symbol::SymbolId};
16+
use oxc_syntax::{
17+
comment_node::CommentNodeId, reference::ReferenceId, scope::ScopeId, symbol::SymbolId,
18+
};
1619

1720
use crate::ast::*;
1821

crates/oxc_ast_macros/src/generated/structs.rs

Lines changed: 253 additions & 252 deletions
Large diffs are not rendered by default.

crates/oxc_syntax/src/comment_node.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//! Comment Node ID.
2+
3+
use oxc_index::Idx;
4+
#[cfg(feature = "serialize")]
5+
use serde::{Serialize, Serializer};
6+
7+
use oxc_allocator::{Allocator, CloneIn, Dummy};
8+
use oxc_ast_macros::ast;
9+
10+
/// Comment Node ID.
11+
#[ast]
12+
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
13+
#[generate_derive(CloneIn)]
14+
#[clone_in(default)]
15+
#[content_eq(skip)]
16+
#[estree(skip)]
17+
pub struct CommentNodeId(u32);
18+
19+
impl CommentNodeId {
20+
/// Mock comment node ID.
21+
///
22+
/// This is used for synthetically-created AST nodes, among other things.
23+
pub const DUMMY: Self = CommentNodeId::new(0);
24+
25+
/// Create `CommentNodeId` from `u32`.
26+
pub const fn new(idx: u32) -> Self {
27+
Self(idx)
28+
}
29+
}
30+
31+
impl Idx for CommentNodeId {
32+
fn from_usize(idx: usize) -> Self {
33+
Self(u32::try_from(idx).expect("`idx` is greater than `u32::MAX`"))
34+
}
35+
36+
fn index(self) -> usize {
37+
self.0 as usize
38+
}
39+
}
40+
41+
impl Default for CommentNodeId {
42+
#[inline]
43+
fn default() -> Self {
44+
Self::DUMMY
45+
}
46+
}
47+
48+
impl<'a> Dummy<'a> for CommentNodeId {
49+
#[inline]
50+
fn dummy(_allocator: &'a Allocator) -> Self {
51+
Self::DUMMY
52+
}
53+
}
54+
55+
#[cfg(feature = "serialize")]
56+
impl Serialize for CommentNodeId {
57+
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
58+
serializer.serialize_u32(self.0)
59+
}
60+
}

crates/oxc_syntax/src/generated/assert_layouts.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,20 @@ use std::mem::{align_of, offset_of, size_of};
77

88
use nonmax::NonMaxU32;
99

10-
use crate::{module_record::*, number::*, operator::*, reference::*, scope::*, symbol::*};
10+
use crate::{
11+
comment_node::*, module_record::*, number::*, operator::*, reference::*, scope::*, symbol::*,
12+
};
1113

1214
#[cfg(target_pointer_width = "64")]
1315
const _: () = {
1416
// Padding: 0 bytes
1517
assert!(size_of::<NonMaxU32>() == 4);
1618
assert!(align_of::<NonMaxU32>() == 4);
1719

20+
// Padding: 0 bytes
21+
assert!(size_of::<CommentNodeId>() == 4);
22+
assert!(align_of::<CommentNodeId>() == 4);
23+
1824
// Padding: 0 bytes
1925
assert!(size_of::<NameSpan>() == 24);
2026
assert!(align_of::<NameSpan>() == 8);
@@ -99,6 +105,10 @@ const _: () = {
99105
assert!(size_of::<NonMaxU32>() == 4);
100106
assert!(align_of::<NonMaxU32>() == 4);
101107

108+
// Padding: 0 bytes
109+
assert!(size_of::<CommentNodeId>() == 4);
110+
assert!(align_of::<CommentNodeId>() == 4);
111+
102112
// Padding: 0 bytes
103113
assert!(size_of::<NameSpan>() == 16);
104114
assert!(align_of::<NameSpan>() == 4);

crates/oxc_syntax/src/generated/derive_clone_in.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,22 @@
55

66
use oxc_allocator::{Allocator, CloneIn};
77

8+
use crate::comment_node::*;
89
use crate::number::*;
910
use crate::operator::*;
1011

12+
impl<'new_alloc> CloneIn<'new_alloc> for CommentNodeId {
13+
type Cloned = CommentNodeId;
14+
15+
fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned {
16+
Default::default()
17+
}
18+
19+
fn clone_in_with_semantic_ids(&self, allocator: &'new_alloc Allocator) -> Self::Cloned {
20+
Default::default()
21+
}
22+
}
23+
1124
impl<'new_alloc> CloneIn<'new_alloc> for NumberBase {
1225
type Cloned = NumberBase;
1326

crates/oxc_syntax/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::num::NonZeroU32;
66
use oxc_ast_macros::ast;
77

88
pub mod class;
9+
pub mod comment_node;
910
pub mod es_target;
1011
pub mod identifier;
1112
pub mod keyword;

crates/oxc_traverse/scripts/lib/ancestor.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ export default function generateAncestorsCode(types) {
112112
}
113113

114114
return `
115+
#![allow(unused_imports)]
115116
#![expect(
116117
clippy::cast_ptr_alignment,
117118
clippy::elidable_lifetime_names,
@@ -124,7 +125,7 @@ export default function generateAncestorsCode(types) {
124125
125126
use oxc_allocator::{Address, Box, GetAddress, Vec};
126127
use oxc_ast::ast::*;
127-
use oxc_syntax::scope::ScopeId;
128+
use oxc_syntax::{comment_node::CommentNodeId, scope::ScopeId};
128129
129130
/// Type of [\`Ancestor\`].
130131
/// Used in [\`crate::TraverseCtx::retag_stack\`].

crates/oxc_traverse/src/generated/ancestor.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Generated by `oxc_traverse/scripts/build.mjs`.
33
// To alter this generated file you have to edit the codegen.
44

5+
#![allow(unused_imports)]
56
#![expect(
67
clippy::cast_ptr_alignment,
78
clippy::elidable_lifetime_names,
@@ -14,7 +15,7 @@ use std::{cell::Cell, marker::PhantomData, mem::offset_of};
1415

1516
use oxc_allocator::{Address, Box, GetAddress, Vec};
1617
use oxc_ast::ast::*;
17-
use oxc_syntax::scope::ScopeId;
18+
use oxc_syntax::{comment_node::CommentNodeId, scope::ScopeId};
1819

1920
/// Type of [`Ancestor`].
2021
/// Used in [`crate::TraverseCtx::retag_stack`].

tasks/ast_tools/src/generators/assert_layouts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,7 @@ fn template(krate: &str, assertions_64: &TokenStream, assertions_32: &TokenStrea
620620
use nonmax::NonMaxU32;
621621

622622
///@@line_break
623-
use crate::{module_record::*, number::*, operator::*, reference::*, scope::*, symbol::*};
623+
use crate::{comment_node::*, module_record::*, number::*, operator::*, reference::*, scope::*, symbol::*};
624624
},
625625
"napi/parser" => quote! {
626626
use crate::raw_transfer_types::*;

0 commit comments

Comments
 (0)