From c660de3f7bda2ba36c9e68f34e6bad8a457d5835 Mon Sep 17 00:00:00 2001 From: Daniel Leite Date: Tue, 22 Nov 2022 13:19:36 +0000 Subject: [PATCH] semantic model improvements --- .../src/semantic_model/binding.rs | 48 +++++-------------- .../src/semantic_model/builder.rs | 19 ++++++-- .../src/semantic_model/reference.rs | 24 ++++++++++ .../src/semantic_model/semantic_model.rs | 22 ++++++++- .../src/tests/declarations.rs | 1 + 5 files changed, 72 insertions(+), 42 deletions(-) diff --git a/crates/rome_js_semantic/src/semantic_model/binding.rs b/crates/rome_js_semantic/src/semantic_model/binding.rs index f43139ce76fc..f6920fe278e3 100644 --- a/crates/rome_js_semantic/src/semantic_model/binding.rs +++ b/crates/rome_js_semantic/src/semantic_model/binding.rs @@ -74,7 +74,7 @@ impl Binding { }) } let first = self.data.bindings[self.id] - .references.get(0) + .references.first() .map(|_| { Reference { data: self.data.clone(), @@ -87,56 +87,30 @@ impl Binding { /// Returns an iterator to all reads references of this binding. pub fn all_reads(&self) -> AllBindingReadReferencesIter { - fn succ_all_reads(current: &Reference) -> Option { - let &id = ¤t.data - .bindings[current.binding_id] - .references - .iter() - .skip(current.id + 1) - .position(|x| x.is_read())?; - Some(Reference { - data: current.data.clone(), - binding_id: current.binding_id, - id: current.id + id, - }) - } - let first = self.data.bindings[self.id] - .references.get(0) - .map(|_| { + let first = self.data + .position_next_reference_read(self.id, 0) + .map(|pos| { Reference { data: self.data.clone(), binding_id: self.id, - id: 0, + id: pos, } }); - std::iter::successors(first, succ_all_reads) + std::iter::successors(first, Reference::find_next_read) } /// Returns an iterator to all write references of this binding. pub fn all_writes(&self) -> AllBindingWriteReferencesIter { - fn succ_all_writes(current: &Reference) -> Option { - let &id = ¤t.data - .bindings[current.binding_id] - .references - .iter() - .skip(current.id + 1) - .position(|x| x.is_write())?; - Some(Reference { - data: current.data.clone(), - binding_id: current.binding_id, - id: current.id + id, - }) - } - let first = self.data.bindings[self.id] - .references.get(0) - .map(|_| { + let first = self.data + .position_next_reference_write(self.id, 0) + .map(|pos| { Reference { data: self.data.clone(), binding_id: self.id, - id: 0, + id: pos, } }); - std::iter::successors(first, succ_all_writes) + std::iter::successors(first, Reference::find_next_write) } } diff --git a/crates/rome_js_semantic/src/semantic_model/builder.rs b/crates/rome_js_semantic/src/semantic_model/builder.rs index 732a613cfbce..baf62699b8a5 100644 --- a/crates/rome_js_semantic/src/semantic_model/builder.rs +++ b/crates/rome_js_semantic/src/semantic_model/builder.rs @@ -111,7 +111,6 @@ impl SemanticModelBuilder { range: range.clone(), references: vec![], }); - dbg!(range); self.bindings_by_range.insert(range, binding_id); let scope = self.scopes @@ -133,11 +132,23 @@ impl SemanticModelBuilder { declared_at: declaration_at, //TODO change to binding_id like we do with scope_id scope_id, } => { - dbg!(declaration_at); - let binding_id = self.bindings_by_range[&declaration_at]; + let binding_id = match self.bindings_by_range.entry(declaration_at) { + Entry::Occupied(entry) => { + *entry.get() + }, + Entry::Vacant(entry) => { + let id = self.bindings.len(); + self.bindings.push(SemanticModelBindingData { + id, + range, + references: vec![] + }); + *entry.insert(id) + }, + }; let binding = &mut self.bindings[binding_id]; - let reference_id = binding.references.len(); + binding.references.push(SemanticModelReference { range, ty: SemanticModelReferenceType::Read { hoisted: false } diff --git a/crates/rome_js_semantic/src/semantic_model/reference.rs b/crates/rome_js_semantic/src/semantic_model/reference.rs index 5c76716e204e..bc3b5ea011c2 100644 --- a/crates/rome_js_semantic/src/semantic_model/reference.rs +++ b/crates/rome_js_semantic/src/semantic_model/reference.rs @@ -10,6 +10,30 @@ pub struct Reference { } impl Reference { + pub(crate) fn find_next_read(&self) -> Option { + self.data + .position_next_reference_read(self.binding_id, self.id + 1) + .map(|pos| { + Reference { + data: self.data.clone(), + binding_id: self.binding_id, + id: pos, + } + }) + } + + pub(crate) fn find_next_write(&self) -> Option { + self.data + .position_next_reference_write(self.binding_id, self.id + 1) + .map(|pos| { + Reference { + data: self.data.clone(), + binding_id: self.binding_id, + id: pos, + } + }) + } + pub fn range(&self) -> &TextRange { let reference = &self.data .bindings[self.binding_id] diff --git a/crates/rome_js_semantic/src/semantic_model/semantic_model.rs b/crates/rome_js_semantic/src/semantic_model/semantic_model.rs index b9a9eec9fa50..3b86dd37fe05 100644 --- a/crates/rome_js_semantic/src/semantic_model/semantic_model.rs +++ b/crates/rome_js_semantic/src/semantic_model/semantic_model.rs @@ -55,6 +55,26 @@ impl SemanticModelData { pub fn is_exported(&self, range: TextRange) -> bool { self.exported.contains(&range) } + + pub fn position_next_reference_read(&self, binding_id: usize, skip_references: usize) -> Option { + let (id, _) = self.bindings[binding_id] + .references + .iter() + .enumerate() + .skip(skip_references) + .find(|(_, reference)| reference.is_read())?; + Some(id) + } + + pub fn position_next_reference_write(&self, binding_id: usize, skip_references: usize) -> Option { + let (id, _) = self.bindings[binding_id] + .references + .iter() + .enumerate() + .skip(skip_references) + .find(|(_, reference)| reference.is_write())?; + Some(id) + } } impl PartialEq for SemanticModelData { @@ -203,7 +223,7 @@ impl SemanticModel { .globals.get(global_id) .and_then(|global| { global.references.get(id) - }).map(|reference| { + }).map(|_| { GlobalReference { data: current.data.clone(), global_id, diff --git a/crates/rome_js_semantic/src/tests/declarations.rs b/crates/rome_js_semantic/src/tests/declarations.rs index 8e11ba86bde2..cf9c40128d75 100644 --- a/crates/rome_js_semantic/src/tests/declarations.rs +++ b/crates/rome_js_semantic/src/tests/declarations.rs @@ -18,6 +18,7 @@ assert_semantics! { // Functions assert_semantics! { ok_declaration_function, ";function/*START A*/ f(a/*#a*//*@A*/) {/*START B*/ let b/*#b*//*@B*/ = 1; }", + ok_declaration_self_invocation, ";(function f/*#F*/() {})();", ok_declaration_arrow_function, ";(/*START A*/ a/*#a*//*@A*/) => {/*START B*/ let b/*#b*//*@B*/ = 1; }", }