Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(js_semantic): minor changes #3416

Merged
merged 1 commit into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading