Skip to content

Commit 71af1aa

Browse files
committed
feat(semantic): add "linter" feature (#14139)
Only the linter pipeline requires `AstNodes::node_kinds_set`.
1 parent ad0e5df commit 71af1aa

File tree

6 files changed

+28
-63
lines changed

6 files changed

+28
-63
lines changed

crates/oxc_linter/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ oxc_macros = { workspace = true, features = ["ruledocs"] }
4040
oxc_parser = { workspace = true }
4141
oxc_regular_expression = { workspace = true }
4242
oxc_resolver = { workspace = true }
43-
oxc_semantic = { workspace = true, features = ["cfg"] }
43+
oxc_semantic = { workspace = true, features = ["cfg", "linter"] }
4444
oxc_span = { workspace = true, features = ["schemars", "serialize"] }
4545
oxc_syntax = { workspace = true, features = ["serialize"] }
4646

crates/oxc_semantic/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,5 @@ serde_json = { workspace = true }
4646
[features]
4747
default = []
4848
cfg = ["dep:oxc_cfg"]
49+
linter = []
4950
serialize = ["oxc_span/serialize", "oxc_syntax/serialize"]

crates/oxc_semantic/src/builder.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ impl<'a> SemanticBuilder<'a> {
336336
kind,
337337
self.current_scope_id,
338338
self.current_node_id,
339+
#[cfg(feature = "cfg")]
339340
control_flow!(self, |cfg| cfg.current_node_ix),
340341
flags,
341342
);
@@ -649,6 +650,7 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
649650
self.current_node_id = self.nodes.add_program_node(
650651
kind,
651652
self.current_scope_id,
653+
#[cfg(feature = "cfg")]
652654
control_flow!(self, |cfg| cfg.current_node_ix),
653655
self.current_node_flags,
654656
);

crates/oxc_semantic/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub use oxc_syntax::{
2424
#[cfg(feature = "cfg")]
2525
pub mod dot;
2626

27+
#[cfg(feature = "linter")]
2728
mod ast_types_bitset;
2829
mod binder;
2930
mod builder;
@@ -38,6 +39,7 @@ mod scoping;
3839
mod stats;
3940
mod unresolved_stack;
4041

42+
#[cfg(feature = "linter")]
4143
pub use ast_types_bitset::AstTypesBitset;
4244
pub use builder::{SemanticBuilder, SemanticBuilderReturn};
4345
pub use is_global_reference::IsGlobalReference;

crates/oxc_semantic/src/node/mod.rs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ pub use nodes::AstNodes;
44

55
use oxc_allocator::{Address, GetAddress};
66
use oxc_ast::AstKind;
7-
#[cfg(feature = "cfg")]
8-
use oxc_cfg::BlockNodeId;
97
use oxc_span::{GetSpan, Span};
108
use oxc_syntax::{node::NodeId, scope::ScopeId};
119

@@ -21,19 +19,7 @@ pub struct AstNode<'a> {
2119
}
2220

2321
impl<'a> AstNode<'a> {
24-
#[inline]
25-
#[cfg(feature = "cfg")]
26-
pub(crate) fn new(
27-
kind: AstKind<'a>,
28-
scope_id: ScopeId,
29-
_cfg_id: BlockNodeId,
30-
id: NodeId,
31-
) -> Self {
32-
Self { id, kind, scope_id }
33-
}
34-
35-
#[cfg(not(feature = "cfg"))]
36-
pub(crate) fn new(kind: AstKind<'a>, scope_id: ScopeId, _cfg_id: (), id: NodeId) -> Self {
22+
pub(crate) fn new(kind: AstKind<'a>, scope_id: ScopeId, id: NodeId) -> Self {
3723
Self { id, kind, scope_id }
3824
}
3925

crates/oxc_semantic/src/node/nodes.rs

Lines changed: 21 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
use std::iter::FusedIterator;
22

3-
use oxc_ast::{AstKind, AstType, ast::Program};
4-
#[cfg(feature = "cfg")]
5-
use oxc_cfg::BlockNodeId;
3+
use oxc_ast::{AstKind, ast::Program};
64
use oxc_index::{IndexSlice, IndexVec};
75
use oxc_syntax::{
86
node::{NodeFlags, NodeId},
97
scope::ScopeId,
108
};
119

10+
#[cfg(feature = "linter")]
11+
use oxc_ast::AstType;
12+
13+
#[cfg(feature = "cfg")]
14+
use oxc_cfg::BlockNodeId;
15+
1216
use super::AstNode;
17+
18+
#[cfg(feature = "linter")]
1319
use crate::ast_types_bitset::AstTypesBitset;
1420

1521
/// Untyped AST nodes flattened into an vec
@@ -26,6 +32,7 @@ pub struct AstNodes<'a> {
2632
/// Stores a set of bits of a fixed size, where each bit represents a single [`AstKind`]. If the bit is set (1),
2733
/// then the AST contains at least one node of that kind. If the bit is not set (0), then the AST does not contain
2834
/// any nodes of that kind.
35+
#[cfg(feature = "linter")]
2936
node_kinds_set: AstTypesBitset,
3037
}
3138

@@ -148,38 +155,21 @@ impl<'a> AstNodes<'a> {
148155
/// [`Program`]: oxc_ast::ast::Program
149156
/// [`add_program_node`]: AstNodes::add_program_node
150157
#[inline]
151-
#[cfg(feature = "cfg")]
152158
pub fn add_node(
153159
&mut self,
154160
kind: AstKind<'a>,
155161
scope_id: ScopeId,
156162
parent_node_id: NodeId,
157-
cfg_id: BlockNodeId,
163+
#[cfg(feature = "cfg")] cfg_id: BlockNodeId,
158164
flags: NodeFlags,
159165
) -> NodeId {
160166
let node_id = self.parent_ids.push(parent_node_id);
161-
let node = AstNode::new(kind, scope_id, cfg_id, node_id);
167+
let node = AstNode::new(kind, scope_id, node_id);
162168
self.nodes.push(node);
163169
self.flags.push(flags);
170+
#[cfg(feature = "cfg")]
164171
self.cfg_ids.push(cfg_id);
165-
self.node_kinds_set.set(kind.ty());
166-
node_id
167-
}
168-
169-
#[inline]
170-
#[cfg(not(feature = "cfg"))]
171-
pub fn add_node(
172-
&mut self,
173-
kind: AstKind<'a>,
174-
scope_id: ScopeId,
175-
parent_node_id: NodeId,
176-
_cfg_id: (),
177-
flags: NodeFlags,
178-
) -> NodeId {
179-
let node_id = self.parent_ids.push(parent_node_id);
180-
let node = AstNode::new(kind, scope_id, (), node_id);
181-
self.nodes.push(node);
182-
self.flags.push(flags);
172+
#[cfg(feature = "linter")]
183173
self.node_kinds_set.set(kind.ty());
184174
node_id
185175
}
@@ -189,12 +179,11 @@ impl<'a> AstNodes<'a> {
189179
/// # Panics
190180
///
191181
/// Panics if this is not the first node being added to the AST.
192-
#[cfg(feature = "cfg")]
193182
pub fn add_program_node(
194183
&mut self,
195184
kind: AstKind<'a>,
196185
scope_id: ScopeId,
197-
cfg_id: BlockNodeId,
186+
#[cfg(feature = "cfg")] cfg_id: BlockNodeId,
198187
flags: NodeFlags,
199188
) -> NodeId {
200189
assert!(self.parent_ids.is_empty(), "Program node must be the first node in the AST.");
@@ -203,29 +192,11 @@ impl<'a> AstNodes<'a> {
203192
"Program node must be of kind `AstKind::Program`"
204193
);
205194
self.parent_ids.push(NodeId::ROOT);
206-
self.nodes.push(AstNode::new(kind, scope_id, cfg_id, NodeId::ROOT));
195+
self.nodes.push(AstNode::new(kind, scope_id, NodeId::ROOT));
207196
self.flags.push(flags);
197+
#[cfg(feature = "cfg")]
208198
self.cfg_ids.push(cfg_id);
209-
self.node_kinds_set.set(AstType::Program);
210-
NodeId::ROOT
211-
}
212-
213-
#[cfg(not(feature = "cfg"))]
214-
pub fn add_program_node(
215-
&mut self,
216-
kind: AstKind<'a>,
217-
scope_id: ScopeId,
218-
_cfg_id: (),
219-
flags: NodeFlags,
220-
) -> NodeId {
221-
assert!(self.parent_ids.is_empty(), "Program node must be the first node in the AST.");
222-
debug_assert!(
223-
matches!(kind, AstKind::Program(_)),
224-
"Program node must be of kind `AstKind::Program`"
225-
);
226-
self.parent_ids.push(NodeId::ROOT);
227-
self.nodes.push(AstNode::new(kind, scope_id, (), NodeId::ROOT));
228-
self.flags.push(flags);
199+
#[cfg(feature = "linter")]
229200
self.node_kinds_set.set(AstType::Program);
230201
NodeId::ROOT
231202
}
@@ -260,6 +231,7 @@ impl<'a> AstNodes<'a> {
260231
/// // `true` if there is at least one import OR one export in the AST
261232
/// nodes.contains_any(&import_export_decl);
262233
/// ```
234+
#[cfg(feature = "linter")]
263235
pub fn contains_any(&self, bitset: &AstTypesBitset) -> bool {
264236
self.node_kinds_set.intersects(bitset)
265237
}
@@ -285,6 +257,7 @@ impl<'a> AstNodes<'a> {
285257
/// // `true` if there is at least one import AND one export in the AST
286258
/// nodes.contains_all(&import_export_decl);
287259
/// ```
260+
#[cfg(feature = "linter")]
288261
pub fn contains_all(&self, bitset: &AstTypesBitset) -> bool {
289262
self.node_kinds_set.contains(bitset)
290263
}
@@ -304,6 +277,7 @@ impl<'a> AstNodes<'a> {
304277
/// // `true` if there is an `ImportDeclaration` anywhere in the AST
305278
/// nodes.contains(AstType::ImportDeclaration);
306279
/// ```
280+
#[cfg(feature = "linter")]
307281
pub fn contains(&self, ty: AstType) -> bool {
308282
self.node_kinds_set.has(ty)
309283
}

0 commit comments

Comments
 (0)