Skip to content

Commit

Permalink
refactor(js_semantic): minor changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Conaclos committed Jul 11, 2024
1 parent 8eb0e8a commit f928b6d
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 105 deletions.
24 changes: 12 additions & 12 deletions crates/biome_js_semantic/src/semantic_model/binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use biome_js_syntax::{binding_ext::AnyJsIdentifierBinding, TextRange, TsTypePara
/// Internal type with all the semantic data of a specific binding
#[derive(Debug)]
pub(crate) struct SemanticModelBindingData {
pub id: BindingIndex,
pub id: BindingId,
pub range: TextRange,
pub references: Vec<SemanticModelReference>,
}
Expand All @@ -18,7 +18,7 @@ pub(crate) enum SemanticModelReferenceType {
/// Internal type with all the semantic data of a specific reference
#[derive(Debug)]
pub(crate) struct SemanticModelReference {
pub(crate) index: ReferenceIndex,
pub(crate) id: ReferenceId,
pub(crate) range: TextRange,
pub(crate) ty: SemanticModelReferenceType,
}
Expand All @@ -45,19 +45,19 @@ pub type AllBindingWriteReferencesIter =
/// Provides access to all semantic data of a specific binding.
pub struct Binding {
pub(crate) data: Rc<SemanticModelData>,
pub(crate) index: BindingIndex,
pub(crate) id: BindingId,
}

impl std::fmt::Debug for Binding {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Binding").field("id", &self.index).finish()
f.debug_struct("Binding").field("id", &self.id).finish()
}
}

impl Binding {
/// Returns the scope of this binding
pub fn scope(&self) -> Scope {
let binding = self.data.binding(self.index);
let binding = self.data.binding(self.id);
let id = self.data.scope(&binding.range); //TODO declaration can have its scope id
Scope {
data: self.data.clone(),
Expand All @@ -67,7 +67,7 @@ impl Binding {

/// Returns the syntax node associated with this binding.
pub fn syntax(&self) -> &JsSyntaxNode {
let binding = self.data.binding(self.index);
let binding = self.data.binding(self.id);
&self.data.binding_node_by_start[&binding.range.start()]
}

Expand All @@ -81,38 +81,38 @@ impl Binding {

/// Returns an iterator to all references of this binding.
pub fn all_references(&self) -> AllBindingReferencesIter {
let binding = self.data.binding(self.index);
let binding = self.data.binding(self.id);
let first = binding.references.first().map(|reference| Reference {
data: self.data.clone(),
index: reference.index,
index: reference.id,
});
std::iter::successors(first, Reference::find_next)
}

/// Returns an iterator to all reads references of this binding.
pub fn all_reads(&self) -> AllBindingReadReferencesIter {
let binding = self.data.binding(self.index);
let binding = self.data.binding(self.id);
let first = binding
.references
.iter()
.find(|x| x.is_read())
.map(|reference| Reference {
data: self.data.clone(),
index: reference.index,
index: reference.id,
});
std::iter::successors(first, Reference::find_next_read)
}

/// Returns an iterator to all write references of this binding.
pub fn all_writes(&self) -> AllBindingWriteReferencesIter {
let binding = self.data.binding(self.index);
let binding = self.data.binding(self.id);
let first = binding
.references
.iter()
.find(|x| x.is_write())
.map(|reference| Reference {
data: self.data.clone(),
index: reference.index,
index: reference.id,
});
std::iter::successors(first, Reference::find_next_write)
}
Expand Down
56 changes: 20 additions & 36 deletions crates/biome_js_semantic/src/semantic_model/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ pub struct SemanticModelBuilder {
scope_hoisted_to_by_range: FxHashMap<TextSize, ScopeId>,
bindings: Vec<SemanticModelBindingData>,
/// maps a binding range start to its index inside SemanticModelBuilder::bindings vec
bindings_by_start: FxHashMap<TextSize, u32>,
bindings_by_start: FxHashMap<TextSize, BindingId>,
/// maps a reference range start to its bindings. u32 points to SemanticModelBuilder::bindings vec
declared_at_by_start: FxHashMap<TextSize, u32>,
declared_at_by_start: FxHashMap<TextSize, BindingId>,
exported: FxHashSet<TextSize>,
unresolved_references: Vec<SemanticModelUnresolvedReference>,
}
Expand Down Expand Up @@ -170,9 +170,9 @@ impl SemanticModelBuilder {
// event extractor
debug_assert!((binding_scope_id.index()) < self.scopes.len());

let binding_id = self.bindings.len() as u32;
let binding_id = BindingId::new(self.bindings.len());
self.bindings.push(SemanticModelBindingData {
id: binding_id.into(),
id: binding_id,
range,
references: vec![],
});
Expand Down Expand Up @@ -202,20 +202,16 @@ impl SemanticModelBuilder {
scope_id,
} => {
let binding_id = self.bindings_by_start[&declaration_at];
let binding = &mut self.bindings[binding_id as usize];
let reference_index = binding.references.len() as u32;

let binding = &mut self.bindings[binding_id.index()];
let reference_id = ReferenceId::new(binding.id, binding.references.len());
binding.references.push(SemanticModelReference {
index: (binding.id, reference_index).into(),
id: reference_id,
range,
ty: SemanticModelReferenceType::Read { hoisted: false },
});

let scope = &mut self.scopes[scope_id.index()];
scope.read_references.push(SemanticModelScopeReference {
binding_id,
reference_id: reference_index,
});
scope.read_references.push(reference_id);

self.declared_at_by_start.insert(range.start(), binding_id);
}
Expand All @@ -225,20 +221,16 @@ impl SemanticModelBuilder {
scope_id,
} => {
let binding_id = self.bindings_by_start[&declaration_at];
let binding = &mut self.bindings[binding_id as usize];
let reference_index = binding.references.len() as u32;

let binding = &mut self.bindings[binding_id.index()];
let reference_id = ReferenceId::new(binding.id, binding.references.len());
binding.references.push(SemanticModelReference {
index: (binding.id, reference_index).into(),
id: reference_id,
range,
ty: SemanticModelReferenceType::Read { hoisted: true },
});

let scope = &mut self.scopes[scope_id.index()];
scope.read_references.push(SemanticModelScopeReference {
binding_id,
reference_id: reference_index,
});
scope.read_references.push(reference_id);

self.declared_at_by_start.insert(range.start(), binding_id);
}
Expand All @@ -248,20 +240,16 @@ impl SemanticModelBuilder {
scope_id,
} => {
let binding_id = self.bindings_by_start[&declaration_at];
let binding = &mut self.bindings[binding_id as usize];

let reference_index = binding.references.len() as u32;
let binding = &mut self.bindings[binding_id.index()];
let reference_id = ReferenceId::new(binding.id, binding.references.len());
binding.references.push(SemanticModelReference {
index: (binding.id, reference_index).into(),
id: reference_id,
range,
ty: SemanticModelReferenceType::Write { hoisted: false },
});

let scope = &mut self.scopes[scope_id.index()];
scope.read_references.push(SemanticModelScopeReference {
binding_id,
reference_id: reference_index,
});
scope.read_references.push(reference_id);

self.declared_at_by_start.insert(range.start(), binding_id);
}
Expand All @@ -271,20 +259,16 @@ impl SemanticModelBuilder {
scope_id,
} => {
let binding_id = self.bindings_by_start[&declaration_at];
let binding = &mut self.bindings[binding_id as usize];

let reference_index = binding.references.len() as u32;
let binding = &mut self.bindings[binding_id.index()];
let reference_id = ReferenceId::new(binding.id, binding.references.len());
binding.references.push(SemanticModelReference {
index: (binding.id, reference_index).into(),
id: reference_id,
range,
ty: SemanticModelReferenceType::Write { hoisted: true },
});

let scope = &mut self.scopes[scope_id.index()];
scope.read_references.push(SemanticModelScopeReference {
binding_id,
reference_id: reference_index,
});
scope.read_references.push(reference_id);

self.declared_at_by_start.insert(range.start(), binding_id);
}
Expand Down
16 changes: 8 additions & 8 deletions crates/biome_js_semantic/src/semantic_model/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ pub struct Capture {
data: Rc<SemanticModelData>,
ty: CaptureType,
node: JsSyntaxNode,
binding_id: BindingIndex,
binding_id: BindingId,
}

impl Capture {
Expand All @@ -101,7 +101,7 @@ impl Capture {
pub fn binding(&self) -> Binding {
Binding {
data: self.data.clone(),
index: self.binding_id,
id: self.binding_id,
}
}

Expand All @@ -121,7 +121,7 @@ pub struct AllCapturesIter {
data: Rc<SemanticModelData>,
closure_range: TextRange,
scopes: Vec<ScopeId>,
references: Vec<SemanticModelScopeReference>,
references: Vec<ReferenceId>,
}

impl Iterator for AllCapturesIter {
Expand All @@ -130,9 +130,9 @@ impl Iterator for AllCapturesIter {
fn next(&mut self) -> Option<Self::Item> {
'references: loop {
while let Some(reference) = self.references.pop() {
let binding = &self.data.bindings[reference.binding_id as usize];
let binding = &self.data.bindings[reference.binding_id().index()];
if self.closure_range.intersect(binding.range).is_none() {
let reference = &binding.references[reference.reference_id as usize];
let reference = &binding.references[reference.index()];
return Some(Capture {
data: self.data.clone(),
node: self.data.binding_node_by_start[&reference.range.start()].clone(), // TODO change node to store the range
Expand All @@ -150,9 +150,9 @@ impl Iterator for AllCapturesIter {
}
self.references.clear();
self.references
.extend(scope.read_references.iter().cloned());
.extend(scope.read_references.iter().copied());
self.references
.extend(scope.write_references.iter().cloned());
.extend(scope.write_references.iter().copied());
self.scopes.extend(scope.children.iter());
continue 'references;
}
Expand Down Expand Up @@ -268,7 +268,7 @@ impl Closure {
let scopes = scope.children.clone();

let mut references = scope.read_references.clone();
references.extend(scope.write_references.iter().cloned());
references.extend(scope.write_references.iter().copied());

AllCapturesIter {
data: self.data.clone(),
Expand Down
59 changes: 35 additions & 24 deletions crates/biome_js_semantic/src/semantic_model/model.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,38 @@
use super::*;
use biome_js_syntax::{AnyJsFunction, AnyJsRoot};

#[derive(Copy, Clone, Debug)]
pub(crate) struct BindingIndex(u32);
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub(crate) struct BindingId(u32);

impl From<u32> for BindingIndex {
fn from(v: u32) -> Self {
BindingIndex(v)
impl BindingId {
pub(crate) fn new(index: usize) -> Self {
// SAFETY: We didn't handle files execedding `u32::MAX` bytes.
// Thus, it isn't possible to execedd `u32::MAX` bindings.
Self(index as u32)
}

pub(crate) fn index(self) -> usize {
self.0 as usize
}
}

#[derive(Copy, Clone, Debug)]
pub(crate) struct ReferenceIndex(u32, u32);
pub(crate) struct ReferenceId(BindingId, u32);

impl ReferenceIndex {
pub(crate) fn binding(&self) -> BindingIndex {
BindingIndex(self.0)
impl ReferenceId {
pub(crate) fn new(binding_id: BindingId, index: usize) -> Self {
// SAFETY: We didn't handle files execedding `u32::MAX` bytes.
// Thus, it isn't possible to execedd `u32::MAX` refernces.
Self(binding_id, index as u32)
}

// Points to [SemanticModel]::bindings vec
pub(crate) fn binding_id(&self) -> BindingId {
self.0
}
}

impl From<(BindingIndex, u32)> for ReferenceIndex {
fn from((binding_index, index): (BindingIndex, u32)) -> Self {
ReferenceIndex(binding_index.0, index)
pub(crate) fn index(self) -> usize {
self.1 as usize
}
}

Expand Down Expand Up @@ -67,11 +78,11 @@ pub(crate) struct SemanticModelData {
pub(crate) binding_node_by_start: FxHashMap<TextSize, JsSyntaxNode>,
pub(crate) scope_node_by_range: FxHashMap<TextRange, JsSyntaxNode>,
// Maps any range start in the code to its bindings (usize points to bindings vec)
pub(crate) declared_at_by_start: FxHashMap<TextSize, u32>,
pub(crate) declared_at_by_start: FxHashMap<TextSize, BindingId>,
// List of all the declarations
pub(crate) bindings: Vec<SemanticModelBindingData>,
// Index bindings by range start
pub(crate) bindings_by_start: FxHashMap<TextSize, u32>,
pub(crate) bindings_by_start: FxHashMap<TextSize, BindingId>,
// All bindings that were exported
pub(crate) exported: FxHashSet<TextSize>,
/// All references that could not be resolved
Expand All @@ -81,17 +92,17 @@ pub(crate) struct SemanticModelData {
}

impl SemanticModelData {
pub(crate) fn binding(&self, index: BindingIndex) -> &SemanticModelBindingData {
pub(crate) fn binding(&self, index: BindingId) -> &SemanticModelBindingData {
&self.bindings[index.0 as usize]
}

pub(crate) fn reference(&self, index: ReferenceIndex) -> &SemanticModelReference {
let binding = &self.bindings[index.0 as usize];
pub(crate) fn reference(&self, index: ReferenceId) -> &SemanticModelReference {
let binding = &self.bindings[index.0.index()];
&binding.references[index.1 as usize]
}

pub(crate) fn next_reference(&self, index: ReferenceIndex) -> Option<&SemanticModelReference> {
let binding = &self.bindings[index.0 as usize];
pub(crate) fn next_reference(&self, index: ReferenceId) -> Option<&SemanticModelReference> {
let binding = &self.bindings[index.0.index()];
binding.references.get(index.1 as usize + 1)
}

Expand Down Expand Up @@ -207,7 +218,7 @@ impl SemanticModel {
pub fn all_bindings(&self) -> impl Iterator<Item = Binding> + '_ {
self.data.bindings.iter().map(|x| Binding {
data: self.data.clone(),
index: x.id,
id: x.id,
})
}

Expand Down Expand Up @@ -240,7 +251,7 @@ impl SemanticModel {
let id = *self.data.declared_at_by_start.get(&range.start())?;
Some(Binding {
data: self.data.clone(),
index: (id).into(),
id,
})
}

Expand Down Expand Up @@ -358,10 +369,10 @@ impl SemanticModel {

pub fn as_binding(&self, binding: &impl IsBindingAstNode) -> Binding {
let range = binding.syntax().text_trimmed_range();
let id = &self.data.bindings_by_start[&range.start()];
let id = self.data.bindings_by_start[&range.start()];
Binding {
data: self.data.clone(),
index: (*id).into(),
id,
}
}

Expand Down
Loading

0 comments on commit f928b6d

Please sign in to comment.