Skip to content

Commit

Permalink
refactor(js_semantic): use u32 for scope id (#3358)
Browse files Browse the repository at this point in the history
  • Loading branch information
Conaclos authored Jul 5, 2024
1 parent 1218c3a commit 3c23f59
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 78 deletions.
46 changes: 18 additions & 28 deletions crates/biome_js_semantic/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ pub enum SemanticEvent {
/// - Type parameters
DeclarationFound {
range: TextRange,
scope_id: usize,
hoisted_scope_id: Option<usize>,
scope_id: u32,
hoisted_scope_id: Option<u32>,
},

/// Tracks where a symbol is read, but only if its declaration is before this reference.
Expand All @@ -34,7 +34,7 @@ pub enum SemanticEvent {
Read {
range: TextRange,
declared_at: TextRange,
scope_id: usize,
scope_id: u32,
},

/// Tracks where a symbol is read, but only if its declaration was hoisted.
Expand All @@ -43,7 +43,7 @@ pub enum SemanticEvent {
HoistedRead {
range: TextRange,
declared_at: TextRange,
scope_id: usize,
scope_id: u32,
},

/// Tracks where a symbol is written, but only if its declaration is before this reference.
Expand All @@ -52,7 +52,7 @@ pub enum SemanticEvent {
Write {
range: TextRange,
declared_at: TextRange,
scope_id: usize,
scope_id: u32,
},

/// Tracks where a symbol is written, but only if its declaration was hoisted.
Expand All @@ -62,7 +62,7 @@ pub enum SemanticEvent {
HoistedWrite {
range: TextRange,
declared_at: TextRange,
scope_id: usize,
scope_id: u32,
},

/// Tracks references that do no have any matching binding
Expand All @@ -77,8 +77,8 @@ pub enum SemanticEvent {
ScopeStarted {
/// Scope range
range: TextRange,
scope_id: usize,
parent_scope_id: Option<usize>,
scope_id: u32,
parent_scope_id: Option<u32>,
is_closure: bool,
},

Expand All @@ -89,7 +89,7 @@ pub enum SemanticEvent {
ScopeEnded {
/// Scope range
range: TextRange,
scope_id: usize,
scope_id: u32,
},

/// Tracks where a symbol is exported.
Expand Down Expand Up @@ -131,7 +131,7 @@ impl SemanticEvent {
/// use biome_js_syntax::*;
/// use biome_js_semantic::*;
/// let tree = parse("let a = 1", JsFileSource::js_script(), JsParserOptions::default());
/// let mut extractor = SemanticEventExtractor::new();
/// let mut extractor = SemanticEventExtractor::default();
/// for e in tree.syntax().preorder() {
/// match e {
/// WalkEvent::Enter(node) => extractor.enter(&node),
Expand All @@ -144,15 +144,15 @@ impl SemanticEvent {
/// }
/// }
/// ```
#[derive(Default, Debug)]
#[derive(Debug, Default)]
pub struct SemanticEventExtractor {
/// Event queue
stash: VecDeque<SemanticEvent>,
/// Stack of scopes
scopes: Vec<Scope>,
/// Number of generated scopes
/// This allows assigning a unique scope id to every scope.
scope_count: usize,
/// This allows assigning a unique id to every scope.
scope_count: u32,
/// At any point this is the set of available bindings and their range in the current scope
bindings: FxHashMap<BindingName, BindingInfo>,
/// Type parameters bound in a `infer T` clause.
Expand Down Expand Up @@ -270,7 +270,7 @@ enum ScopeHoisting {

#[derive(Debug)]
struct Scope {
scope_id: usize,
scope_id: u32,
/// All bindings declared inside this scope
bindings: Vec<BindingName>,
/// References that still needs to be bound and will be solved at the end of the scope
Expand All @@ -282,16 +282,6 @@ struct Scope {
}

impl SemanticEventExtractor {
pub fn new() -> Self {
Self {
stash: VecDeque::new(),
scopes: vec![],
scope_count: 0,
bindings: FxHashMap::default(),
infers: vec![],
}
}

/// See [SemanticEvent] for a more detailed description of which events [JsSyntaxNode] generates.
#[inline]
pub fn enter(&mut self, node: &JsSyntaxNode) {
Expand Down Expand Up @@ -980,8 +970,8 @@ impl SemanticEventExtractor {
///
/// This method when called inside the `f` scope will return
/// the `f` scope index.
fn scope_index_to_hoist_declarations(&mut self, skip: usize) -> Option<usize> {
debug_assert!(self.scopes.len() > skip);
fn scope_index_to_hoist_declarations(&mut self, skip: u32) -> Option<u32> {
debug_assert!(self.scopes.len() > (skip as usize));
// We should at least have the global scope
// that do not hoist
debug_assert!(matches!(
Expand All @@ -991,7 +981,7 @@ impl SemanticEventExtractor {
self.scopes
.iter()
.rev()
.skip(skip)
.skip(skip as usize)
.find(|scope| scope.hoisting == ScopeHoisting::DontHoistDeclarationsToParent)
.map(|x| x.scope_id)
.filter(|scope_id| self.current_scope_mut().scope_id != *scope_id)
Expand All @@ -1000,7 +990,7 @@ impl SemanticEventExtractor {
/// Push the binding `binding` into the hoisted scope if it exists, or into the current scope.
fn push_binding(
&mut self,
hoisted_scope_id: Option<usize>,
hoisted_scope_id: Option<u32>,
binding_name: BindingName,
binding_info: BindingInfo,
) {
Expand Down
22 changes: 12 additions & 10 deletions crates/biome_js_semantic/src/semantic_model/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ pub struct SemanticModelBuilder {
globals: Vec<SemanticModelGlobalBindingData>,
globals_by_name: FxHashMap<String, Option<usize>>,
scopes: Vec<SemanticModelScopeData>,
scope_range_by_start: FxHashMap<TextSize, BTreeSet<Interval<usize, usize>>>,
scope_hoisted_to_by_range: FxHashMap<TextSize, usize>,
scope_range_by_start: FxHashMap<TextSize, BTreeSet<Interval<u32, u32>>>,
scope_hoisted_to_by_range: FxHashMap<TextSize, u32>,
bindings: Vec<SemanticModelBindingData>,
/// maps a binding range start to its index inside SemanticModelBuilder::bindings vec
bindings_by_start: FxHashMap<TextSize, usize>,
Expand Down Expand Up @@ -127,7 +127,7 @@ impl SemanticModelBuilder {
is_closure,
} => {
// Scopes will be raised in order
debug_assert!(scope_id == self.scopes.len());
debug_assert!((scope_id as usize) == self.scopes.len());

self.scopes.push(SemanticModelScopeData {
range,
Expand All @@ -141,7 +141,9 @@ impl SemanticModelBuilder {
});

if let Some(parent_scope_id) = parent_scope_id {
self.scopes[parent_scope_id].children.push(scope_id);
self.scopes[parent_scope_id as usize]
.children
.push(scope_id);
}

let start = range.start();
Expand All @@ -164,7 +166,7 @@ impl SemanticModelBuilder {

// SAFETY: this scope id is guaranteed to exist because they were generated by the
// event extractor
debug_assert!(binding_scope_id < self.scopes.len());
debug_assert!((binding_scope_id as usize) < self.scopes.len());

let binding_id = self.bindings.len();
self.bindings.push(SemanticModelBindingData {
Expand All @@ -174,7 +176,7 @@ impl SemanticModelBuilder {
});
self.bindings_by_start.insert(range.start(), binding_id);

let scope = &mut self.scopes[binding_scope_id];
let scope = &mut self.scopes[binding_scope_id as usize];

scope.bindings.push(binding_id);
// Handle bindings with a bogus name
Expand Down Expand Up @@ -218,7 +220,7 @@ impl SemanticModelBuilder {
ty: SemanticModelReferenceType::Read { hoisted: false },
});

let scope = &mut self.scopes[scope_id];
let scope = &mut self.scopes[scope_id as usize];
scope.read_references.push(SemanticModelScopeReference {
binding_id,
reference_id: reference_index,
Expand All @@ -241,7 +243,7 @@ impl SemanticModelBuilder {
ty: SemanticModelReferenceType::Read { hoisted: true },
});

let scope = &mut self.scopes[scope_id];
let scope = &mut self.scopes[scope_id as usize];
scope.read_references.push(SemanticModelScopeReference {
binding_id,
reference_id: reference_index,
Expand All @@ -264,7 +266,7 @@ impl SemanticModelBuilder {
ty: SemanticModelReferenceType::Write { hoisted: false },
});

let scope = &mut self.scopes[scope_id];
let scope = &mut self.scopes[scope_id as usize];
scope.read_references.push(SemanticModelScopeReference {
binding_id,
reference_id: reference_index,
Expand All @@ -287,7 +289,7 @@ impl SemanticModelBuilder {
ty: SemanticModelReferenceType::Write { hoisted: true },
});

let scope = &mut self.scopes[scope_id];
let scope = &mut self.scopes[scope_id as usize];
scope.read_references.push(SemanticModelScopeReference {
binding_id,
reference_id: reference_index,
Expand Down
20 changes: 10 additions & 10 deletions crates/biome_js_semantic/src/semantic_model/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ impl Capture {
pub struct AllCapturesIter {
data: Rc<SemanticModelData>,
closure_range: TextRange,
scopes: Vec<usize>,
scopes: Vec<u32>,
references: Vec<SemanticModelScopeReference>,
}

Expand All @@ -143,7 +143,7 @@ impl Iterator for AllCapturesIter {
}

'scopes: while let Some(scope_id) = self.scopes.pop() {
let scope = &self.data.scopes[scope_id];
let scope = &self.data.scopes[scope_id as usize];

if scope.is_closure {
continue 'scopes;
Expand All @@ -167,15 +167,15 @@ impl FusedIterator for AllCapturesIter {}
/// Iterate all immediate children closures of a specific closure
pub struct ChildrenIter {
data: Rc<SemanticModelData>,
scopes: Vec<usize>,
scopes: Vec<u32>,
}

impl Iterator for ChildrenIter {
type Item = Closure;

fn next(&mut self) -> Option<Self::Item> {
while let Some(scope_id) = self.scopes.pop() {
let scope = &self.data.scopes[scope_id];
let scope = &self.data.scopes[scope_id as usize];
if scope.is_closure {
return Some(Closure {
data: self.data.clone(),
Expand All @@ -196,15 +196,15 @@ impl FusedIterator for ChildrenIter {}
/// Iterate all descendents closures of a specific closure
pub struct DescendentsIter {
data: Rc<SemanticModelData>,
scopes: Vec<usize>,
scopes: Vec<u32>,
}

impl Iterator for DescendentsIter {
type Item = Closure;

fn next(&mut self) -> Option<Self::Item> {
while let Some(scope_id) = self.scopes.pop() {
let scope = &self.data.scopes[scope_id];
let scope = &self.data.scopes[scope_id as usize];
self.scopes.extend(scope.children.iter());
if scope.is_closure {
return Some(Closure {
Expand All @@ -225,7 +225,7 @@ impl FusedIterator for DescendentsIter {}
#[derive(Clone)]
pub struct Closure {
data: Rc<SemanticModelData>,
scope_id: usize,
scope_id: u32,
closure_range: TextRange,
}

Expand All @@ -243,7 +243,7 @@ impl Closure {

pub(super) fn from_scope(
data: Rc<SemanticModelData>,
scope_id: usize,
scope_id: u32,
closure_range: &TextRange,
) -> Option<Closure> {
let node = &data.node_by_range[closure_range];
Expand Down Expand Up @@ -278,7 +278,7 @@ impl Closure {
/// assert!(model.closure(function_f).all_captures(), &["a"]);
/// ```
pub fn all_captures(&self) -> impl Iterator<Item = Capture> {
let scope = &self.data.scopes[self.scope_id];
let scope = &self.data.scopes[self.scope_id as usize];

let scopes = scope.children.clone();

Expand Down Expand Up @@ -308,7 +308,7 @@ impl Closure {
/// assert!(model.closure(function_f).children(), &["g"]);
/// ```
pub fn children(&self) -> impl Iterator<Item = Closure> {
let scope = &self.data.scopes[self.scope_id];
let scope = &self.data.scopes[self.scope_id as usize];
ChildrenIter {
data: self.data.clone(),
scopes: scope.children.clone(),
Expand Down
10 changes: 5 additions & 5 deletions crates/biome_js_semantic/src/semantic_model/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ pub(crate) struct SemanticModelData {
pub(crate) root: AnyJsRoot,
// All scopes of this model
pub(crate) scopes: Vec<SemanticModelScopeData>,
pub(crate) scope_by_range: rust_lapper::Lapper<usize, usize>,
pub(crate) scope_by_range: rust_lapper::Lapper<u32, u32>,
// Maps the start of a node range to a scope id
pub(crate) scope_hoisted_to_by_range: FxHashMap<TextSize, usize>,
pub(crate) scope_hoisted_to_by_range: FxHashMap<TextSize, u32>,
// Map to each by its range
pub(crate) node_by_range: FxHashMap<TextRange, JsSyntaxNode>,
// Maps any range start in the code to its bindings (usize points to bindings vec)
Expand Down Expand Up @@ -68,7 +68,7 @@ impl SemanticModelData {
binding.references.get(index.1 + 1)
}

pub(crate) fn scope(&self, range: &TextRange) -> usize {
pub(crate) fn scope(&self, range: &TextRange) -> u32 {
let start = range.start().into();
let end = range.end().into();
let scopes = self
Expand All @@ -84,7 +84,7 @@ impl SemanticModelData {
}
}

fn scope_hoisted_to(&self, range: &TextRange) -> Option<usize> {
fn scope_hoisted_to(&self, range: &TextRange) -> Option<u32> {
self.scope_hoisted_to_by_range.get(&range.start()).copied()
}

Expand Down Expand Up @@ -122,7 +122,7 @@ impl SemanticModel {
pub fn scopes(&self) -> impl Iterator<Item = Scope> + '_ {
self.data.scopes.iter().enumerate().map(|(id, _)| Scope {
data: self.data.clone(),
id,
id: id as u32,
})
}

Expand Down
Loading

0 comments on commit 3c23f59

Please sign in to comment.