From 9d7cfa764be0f226b46161ed15fb5c1319b11527 Mon Sep 17 00:00:00 2001 From: Daniel Leite Date: Tue, 22 Nov 2022 13:43:02 +0000 Subject: [PATCH] only accept nodes that can be returned --- crates/rome_js_semantic/src/events.rs | 38 +++++++++++---- .../src/semantic_model/builder.rs | 46 ++++++++++++++++++- .../src/semantic_model/closure.rs | 9 ++-- .../src/semantic_model/scope.rs | 2 + 4 files changed, 79 insertions(+), 16 deletions(-) diff --git a/crates/rome_js_semantic/src/events.rs b/crates/rome_js_semantic/src/events.rs index 0eb5f725a8d3..610ce95e27be 100644 --- a/crates/rome_js_semantic/src/events.rs +++ b/crates/rome_js_semantic/src/events.rs @@ -81,6 +81,7 @@ pub enum SemanticEvent { range: TextRange, scope_id: usize, parent_scope_id: Option, + is_closure: bool }, /// Tracks where a scope ends @@ -261,21 +262,30 @@ impl SemanticEventExtractor { JS_MODULE | JS_SCRIPT => self.push_scope( node.text_range(), ScopeHoisting::DontHoistDeclarationsToParent, + false ), + JS_FUNCTION_DECLARATION - | JS_FUNCTION_EXPORT_DEFAULT_DECLARATION | JS_FUNCTION_EXPRESSION | JS_ARROW_FUNCTION_EXPRESSION - | JS_CLASS_DECLARATION - | JS_CLASS_EXPORT_DEFAULT_DECLARATION - | JS_CLASS_EXPRESSION | JS_CONSTRUCTOR_CLASS_MEMBER | JS_METHOD_CLASS_MEMBER | JS_GETTER_CLASS_MEMBER | JS_SETTER_CLASS_MEMBER | JS_METHOD_OBJECT_MEMBER | JS_GETTER_OBJECT_MEMBER - | JS_SETTER_OBJECT_MEMBER + | JS_SETTER_OBJECT_MEMBER => { + self.push_scope( + node.text_range(), + ScopeHoisting::DontHoistDeclarationsToParent, + true + ); + }, + + JS_FUNCTION_EXPORT_DEFAULT_DECLARATION + | JS_CLASS_DECLARATION + | JS_CLASS_EXPORT_DEFAULT_DECLARATION + | JS_CLASS_EXPRESSION | JS_FUNCTION_BODY | TS_INTERFACE_DECLARATION | TS_ENUM_DECLARATION @@ -284,12 +294,21 @@ impl SemanticEventExtractor { self.push_scope( node.text_range(), ScopeHoisting::DontHoistDeclarationsToParent, + false ); } - JS_BLOCK_STATEMENT | JS_FOR_STATEMENT | JS_FOR_OF_STATEMENT | JS_FOR_IN_STATEMENT - | JS_SWITCH_STATEMENT | JS_CATCH_CLAUSE => { - self.push_scope(node.text_range(), ScopeHoisting::HoistDeclarationsToParent); + JS_BLOCK_STATEMENT + | JS_FOR_STATEMENT + | JS_FOR_OF_STATEMENT + | JS_FOR_IN_STATEMENT + | JS_SWITCH_STATEMENT + | JS_CATCH_CLAUSE => { + self.push_scope( + node.text_range(), + ScopeHoisting::HoistDeclarationsToParent, + false + ); } _ => {} @@ -516,7 +535,7 @@ impl SemanticEventExtractor { self.stash.pop_front() } - fn push_scope(&mut self, range: TextRange, hoisting: ScopeHoisting) { + fn push_scope(&mut self, range: TextRange, hoisting: ScopeHoisting, is_closure: bool) { let scope_id = self.next_scope_id; self.next_scope_id += 1; @@ -526,6 +545,7 @@ impl SemanticEventExtractor { range, scope_id, parent_scope_id, + is_closure, }); self.scopes.push(Scope { diff --git a/crates/rome_js_semantic/src/semantic_model/builder.rs b/crates/rome_js_semantic/src/semantic_model/builder.rs index baf62699b8a5..dca51885b546 100644 --- a/crates/rome_js_semantic/src/semantic_model/builder.rs +++ b/crates/rome_js_semantic/src/semantic_model/builder.rs @@ -47,7 +47,49 @@ impl SemanticModelBuilder { #[inline] pub fn push_node(&mut self, node: &JsSyntaxNode) { - self.node_by_range.insert(node.text_range(), node.clone()); + use JsSyntaxKind::*; + match node.kind() { + // Acessible from bindings and references + JS_IDENTIFIER_BINDING + | TS_IDENTIFIER_BINDING + | JS_REFERENCE_IDENTIFIER + | JSX_REFERENCE_IDENTIFIER + | JS_IDENTIFIER_ASSIGNMENT => { + self.node_by_range.insert(node.text_range(), node.clone()); + } + + // Acessible from scopes, closures + JS_MODULE + | JS_SCRIPT + | JS_FUNCTION_DECLARATION + | JS_FUNCTION_EXPRESSION + | JS_ARROW_FUNCTION_EXPRESSION + | JS_CONSTRUCTOR_CLASS_MEMBER + | JS_METHOD_CLASS_MEMBER + | JS_GETTER_CLASS_MEMBER + | JS_SETTER_CLASS_MEMBER + | JS_METHOD_OBJECT_MEMBER + | JS_GETTER_OBJECT_MEMBER + | JS_SETTER_OBJECT_MEMBER + | JS_FUNCTION_EXPORT_DEFAULT_DECLARATION + | JS_CLASS_DECLARATION + | JS_CLASS_EXPORT_DEFAULT_DECLARATION + | JS_CLASS_EXPRESSION + | JS_FUNCTION_BODY + | TS_INTERFACE_DECLARATION + | TS_ENUM_DECLARATION + | TS_TYPE_ALIAS_DECLARATION + | TS_FUNCTION_TYPE + | JS_BLOCK_STATEMENT + | JS_FOR_STATEMENT + | JS_FOR_OF_STATEMENT + | JS_FOR_IN_STATEMENT + | JS_SWITCH_STATEMENT + | JS_CATCH_CLAUSE => { + self.node_by_range.insert(node.text_range(), node.clone()); + } + _ => {} + } } #[inline] @@ -63,6 +105,7 @@ impl SemanticModelBuilder { range, parent_scope_id, scope_id, + is_closure } => { // Scopes will be raised in order debug_assert!(scope_id == self.scopes.len()); @@ -75,6 +118,7 @@ impl SemanticModelBuilder { bindings_by_name: FxHashMap::default(), read_references: vec![], write_references: vec![], + is_closure }); if let Some(parent_scope_id) = parent_scope_id { diff --git a/crates/rome_js_semantic/src/semantic_model/closure.rs b/crates/rome_js_semantic/src/semantic_model/closure.rs index 710ca73728bb..2ea1dcff26f8 100644 --- a/crates/rome_js_semantic/src/semantic_model/closure.rs +++ b/crates/rome_js_semantic/src/semantic_model/closure.rs @@ -145,9 +145,8 @@ impl Iterator for AllCapturesIter { 'scopes: while let Some(scope_id) = self.scopes.pop() { let scope = &self.data.scopes[scope_id]; - let node = &self.data.node_by_range[&scope.range]; - if AnyHasClosureNode::from_node(node).is_some() { + if scope.is_closure { continue 'scopes; } else { self.references.clear(); @@ -179,8 +178,7 @@ impl Iterator for ChildrenIter { fn next(&mut self) -> Option { while let Some(scope_id) = self.scopes.pop() { let scope = &self.data.scopes[scope_id]; - let node = &self.data.node_by_range[&scope.range]; - if AnyHasClosureNode::from_node(node).is_some() { + if scope.is_closure { return Some(Closure { data: self.data.clone(), scope_id, @@ -209,9 +207,8 @@ impl Iterator for DescendentsIter { fn next(&mut self) -> Option { while let Some(scope_id) = self.scopes.pop() { let scope = &self.data.scopes[scope_id]; - let node = &self.data.node_by_range[&scope.range]; self.scopes.extend(scope.children.iter()); - if AnyHasClosureNode::from_node(node).is_some() { + if scope.is_closure { return Some(Closure { data: self.data.clone(), scope_id, diff --git a/crates/rome_js_semantic/src/semantic_model/scope.rs b/crates/rome_js_semantic/src/semantic_model/scope.rs index 2558ea352ccb..e6ae2f1286ea 100644 --- a/crates/rome_js_semantic/src/semantic_model/scope.rs +++ b/crates/rome_js_semantic/src/semantic_model/scope.rs @@ -20,6 +20,8 @@ pub(crate) struct SemanticModelScopeData { pub(crate) read_references: Vec, // All write references of a scope pub(crate) write_references: Vec, + // Identify if this scope is from a closure or not + pub(crate) is_closure: bool, } /// Provides all information regarding a specific scope.