diff --git a/crates/analysis/src/utils/visitors/position_filter.rs b/crates/analysis/src/utils/visitors/position_filter.rs index e0bb29b..bc82253 100644 --- a/crates/analysis/src/utils/visitors/position_filter.rs +++ b/crates/analysis/src/utils/visitors/position_filter.rs @@ -1,6 +1,6 @@ use std::{cell::RefCell, rc::Rc}; use lsp_types as lsp; -use witcherscript::{ast::*, tokens::*}; +use witcherscript::{ast::*, tokens::*, AnyNode}; /// Utility node visitor travels only through nodes that span a specified position @@ -26,15 +26,73 @@ pub struct PositionFilter { #[derive(Debug, Clone, Default)] pub struct PositionFilterPayload { - /// Signals that the given node likely directly contains a node, - /// which spans the specified position - pub done: bool + /// Signals that the given node directly contains a child leaf node, + /// which spans the specified position. + pub leaf_endpoint: Option } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum PositionFilterEndpoint { + Current, + + + ClassSpecifier { nth: usize }, + ClassName, + ClassBase, + + StateSpecifier { nth: usize }, + StateName, + StateParent, + StateBase, + + StructSpecifier { nth: usize }, + StructName, + + EnumName, + EnumVariantName, + EnumVariantValue, + + + FunctionSpecifier { nth: usize }, + FunctionFlavour, + FunctionName, + EventName, + + FunctionParameterSpecifier { nth: usize }, + FunctionParameterName { nth: usize }, + + MemberDefaultValueMember, + MemberHintMember, + MemberHintValue, + + VarSpecifier { nth: usize }, + VarName { nth: usize }, + + AutobindSpecifier { nth: usize }, + AutobindName, + AutobindValue, + + + MemberAccessExpressionMember, + NewExpressionClass, + TypeCastExpressionTargetType, + UnaryOperationExpressionOp, + BinaryOperationExpressionOp, + AssignmentOperationExpressionOp, + + + TypeAnnotationTypeName, + + + AnnotationName, + AnnotationArg +} + + impl PositionFilter { pub fn new(position: lsp::Position) -> (Self, Rc>) { let payload = Rc::new(RefCell::new(PositionFilterPayload { - done: false + leaf_endpoint: None })); let self_ = Self { @@ -57,7 +115,7 @@ impl PositionFilter { pub fn reset(&mut self, position: lsp::Position) { self.pos = position; self.currently_in_range = false; - self.payload.borrow_mut().done = false; + self.payload.borrow_mut().leaf_endpoint.take(); } } @@ -70,10 +128,7 @@ impl SyntaxNodeVisitor for PositionFilter { fn visit_root(&mut self, n: &RootNode) -> RootTraversalPolicy { self.currently_in_range = n.spans_position(self.pos); - RootTraversalPolicy { - traverse_statements: self.currently_in_range, - traverse_errors: false - } + RootTraversalPolicy::default_to(self.currently_in_range) } fn visit_class_decl(&mut self, n: &ClassDeclarationNode) -> ClassDeclarationTraversalPolicy { @@ -83,9 +138,21 @@ impl SyntaxNodeVisitor for PositionFilter { if self.currently_in_range { if n.definition().spans_position(self.pos) { tp.traverse_definition = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; + } + else if let Some(speci) = n.specifiers().enumerate().find(|(_, s)| s.spans_position(self.pos)).map(|(i, _)| i) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::ClassSpecifier { nth: speci }); + } + else if n.name().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::ClassName); + } + else if n.base().map(|b| b.spans_position(self.pos)).unwrap_or(false) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::ClassBase); } - else { - self.payload.borrow_mut().done = true; + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -99,9 +166,24 @@ impl SyntaxNodeVisitor for PositionFilter { if self.currently_in_range { if n.definition().spans_position(self.pos) { tp.traverse_definition = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } - else { - self.payload.borrow_mut().done = true; + else if let Some(speci) = n.specifiers().enumerate().find(|(_, s)| s.spans_position(self.pos)).map(|(i, _)| i) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::StateSpecifier { nth: speci }); + } + else if n.name().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::StateName); + } + else if n.parent().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::StateParent); + } + else if n.base().map(|b| b.spans_position(self.pos)).unwrap_or(false) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::StateBase); + } + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -115,9 +197,18 @@ impl SyntaxNodeVisitor for PositionFilter { if self.currently_in_range { if n.definition().spans_position(self.pos) { tp.traverse_definition = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } - else { - self.payload.borrow_mut().done = true; + else if let Some(speci) = n.specifiers().enumerate().find(|(_, s)| s.spans_position(self.pos)).map(|(i, _)| i) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::StructSpecifier { nth: speci }); + } + else if n.name().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::StructName); + } + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -131,9 +222,15 @@ impl SyntaxNodeVisitor for PositionFilter { if self.currently_in_range { if n.definition().spans_position(self.pos) { tp.traverse_definition = true; - } - else { - self.payload.borrow_mut().done = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; + } + else if n.name().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::EnumName); + } + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -141,12 +238,26 @@ impl SyntaxNodeVisitor for PositionFilter { } fn visit_enum_variant_decl(&mut self, n: &EnumVariantDeclarationNode) -> EnumVariantDeclarationTraversalPolicy { + let mut tp = EnumVariantDeclarationTraversalPolicy::default_to(false); + self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { - self.payload.borrow_mut().done = true; + if n.name().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::EnumVariantName); + } + else if n.value().map(|v| match v { + EnumVariantValue::Int(n) => n.spans_position(self.pos), + EnumVariantValue::Hex(n) => n.spans_position(self.pos), + }).unwrap_or(false) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::EnumVariantValue); + } + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; + } } - TraversalPolicy::default_to(false) + tp } fn visit_global_func_decl(&mut self, n: &FunctionDeclarationNode) -> FunctionDeclarationTraversalPolicy { @@ -161,15 +272,29 @@ impl SyntaxNodeVisitor for PositionFilter { } else if n.params().spans_position(self.pos) { tp.traverse_params = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } else if n.definition().spans_position(self.pos) { tp.traverse_definition = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } else if n.return_type().map(|rt| rt.spans_position(self.pos)).unwrap_or(false) { tp.traverse_return_type = true; } + else if let Some(speci) = n.specifiers().enumerate().find(|(_, s)| s.spans_position(self.pos)).map(|(i, _)| i) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::FunctionSpecifier { nth: speci }); + } + else if n.flavour().map(|f| f.spans_position(self.pos)).unwrap_or(false) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::FunctionFlavour); + } + else if n.name().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::FunctionName); + } else { - self.payload.borrow_mut().done = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -188,10 +313,18 @@ impl SyntaxNodeVisitor for PositionFilter { if n.annotation().map(|annot| annot.spans_position(self.pos)).unwrap_or(false) { tp.traverse_annotation = true; } - if n.var_type().spans_position(self.pos) { + else if n.var_type().spans_position(self.pos) { tp.traverse_type = true; - } else { - self.payload.borrow_mut().done = true; + } + else if let Some(speci) = n.specifiers().enumerate().find(|(_, s)| s.spans_position(self.pos)).map(|(i, _)| i) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::VarSpecifier { nth: speci }); + } + else if let Some(namei) = n.names().enumerate().find(|(_, n)| n.spans_position(self.pos)).map(|(i, _)| i) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::VarName { nth: namei }); + } + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -213,15 +346,29 @@ impl SyntaxNodeVisitor for PositionFilter { } else if n.params().spans_position(self.pos) { tp.traverse_params = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } else if n.return_type().map(|rt| rt.spans_position(self.pos)).unwrap_or(false) { tp.traverse_return_type = true; } else if n.definition().spans_position(self.pos) { tp.traverse_definition = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; + } + else if let Some(speci) = n.specifiers().enumerate().find(|(_, s)| s.spans_position(self.pos)).map(|(i, _)| i) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::FunctionSpecifier { nth: speci }); + } + else if n.flavour().map(|f| f.spans_position(self.pos)).unwrap_or(false) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::FunctionFlavour); + } + else if n.name().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::FunctionName); } else { - self.payload.borrow_mut().done = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -240,15 +387,23 @@ impl SyntaxNodeVisitor for PositionFilter { self.currently_in_callable_range = true; if n.params().spans_position(self.pos) { tp.traverse_params = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } else if n.return_type().map(|rt| rt.spans_position(self.pos)).unwrap_or(false) { tp.traverse_return_type = true; } else if n.definition().spans_position(self.pos) { tp.traverse_definition = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } + else if n.name().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::EventName); + } else { - self.payload.borrow_mut().done = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -266,8 +421,16 @@ impl SyntaxNodeVisitor for PositionFilter { if self.currently_in_range { if n.param_type().spans_position(self.pos) { tp.traverse_type = true; - } else { - self.payload.borrow_mut().done = true; + } + else if let Some(speci) = n.specifiers().enumerate().find(|(_, s)| s.spans_position(self.pos)).map(|(i, _)| i) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::FunctionParameterSpecifier { nth: speci }); + } + else if let Some(namei) = n.names().enumerate().find(|(_, n)| n.spans_position(self.pos)).map(|(i, _)| i) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::FunctionParameterName { nth: namei }); + } + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -283,8 +446,16 @@ impl SyntaxNodeVisitor for PositionFilter { if n.var_type().spans_position(self.pos) { tp.traverse_type = true; - } else { - self.payload.borrow_mut().done = true; + } + else if let Some(speci) = n.specifiers().enumerate().find(|(_, s)| s.spans_position(self.pos)).map(|(i, _)| i) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::VarSpecifier { nth: speci }); + } + else if let Some(namei) = n.names().enumerate().find(|(_, n)| n.spans_position(self.pos)).map(|(i, _)| i) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::VarName { nth: namei }); + } + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -296,10 +467,24 @@ impl SyntaxNodeVisitor for PositionFilter { self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { - if n.autobind_type().spans_position(self.pos) { + if let Some(speci) = n.specifiers().enumerate().find(|(_, s)| s.spans_position(self.pos)).map(|(i, _)| i) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::AutobindSpecifier { nth: speci }); + } + else if n.name().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::AutobindName); + } + else if n.autobind_type().spans_position(self.pos) { tp.traverse_type = true; - } else { - self.payload.borrow_mut().done = true; + } + else if match n.value() { + AutobindValue::Single(n) => n.spans_position(self.pos), + AutobindValue::Concrete(n) => n.spans_position(self.pos), + } { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::AutobindValue); + } + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -307,12 +492,23 @@ impl SyntaxNodeVisitor for PositionFilter { } fn visit_member_hint(&mut self, n: &MemberHintNode, _: &TraversalContextStack) -> MemberHintTraversalPolicy { + let mut tp = MemberHintTraversalPolicy::default_to(false); + self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { - self.payload.borrow_mut().done = true; + if n.member().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::MemberHintMember); + } + else if n.value().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::MemberHintValue); + } + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; + } } - TraversalPolicy::default_to(false) + tp } fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode, _: &TraversalContextStack) -> MemberDefaultValueTraversalPolicy { @@ -323,8 +519,12 @@ impl SyntaxNodeVisitor for PositionFilter { if n.value().spans_position(self.pos) { tp.traverse_value = true; } + else if n.member().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::MemberDefaultValueMember); + } else { - self.payload.borrow_mut().done = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -337,6 +537,8 @@ impl SyntaxNodeVisitor for PositionFilter { self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { tp.traverse_assignments = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } tp @@ -350,8 +552,12 @@ impl SyntaxNodeVisitor for PositionFilter { if n.value().spans_position(self.pos) { tp.traverse_value = true; } + else if n.member().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::MemberDefaultValueMember); + } else { - self.payload.borrow_mut().done = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -372,8 +578,12 @@ impl SyntaxNodeVisitor for PositionFilter { else if n.var_type().spans_position(self.pos) { tp.traverse_type = true; } - else { - self.payload.borrow_mut().done = true; + else if let Some(namei) = n.names().enumerate().find(|(_, n)| n.spans_position(self.pos)).map(|(i, _)| i) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::VarName { nth: namei }); + } + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -386,6 +596,8 @@ impl SyntaxNodeVisitor for PositionFilter { self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { tp.traverse_statements = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } tp @@ -408,8 +620,9 @@ impl SyntaxNodeVisitor for PositionFilter { else if n.body().spans_position(self.pos) { tp.traverse_body = true; } - else { - self.payload.borrow_mut().done = true; + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -427,8 +640,9 @@ impl SyntaxNodeVisitor for PositionFilter { else if n.body().spans_position(self.pos) { tp.traverse_body = true; } - else { - self.payload.borrow_mut().done = true; + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -446,8 +660,9 @@ impl SyntaxNodeVisitor for PositionFilter { else if n.body().spans_position(self.pos) { tp.traverse_body = true; } - else { - self.payload.borrow_mut().done = true; + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -468,8 +683,9 @@ impl SyntaxNodeVisitor for PositionFilter { else if n.else_body().map(|else_body| else_body.spans_position(self.pos)).unwrap_or(false) { tp.traverse_else_body = true; } - else { - self.payload.borrow_mut().done = true; + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -486,9 +702,12 @@ impl SyntaxNodeVisitor for PositionFilter { } else if n.body().spans_position(self.pos) { tp.traverse_body = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } - else { - self.payload.borrow_mut().done = true; + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -503,8 +722,9 @@ impl SyntaxNodeVisitor for PositionFilter { if n.value().spans_position(self.pos) { tp.traverse_value = true; } - else { - self.payload.borrow_mut().done = true; + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -512,30 +732,39 @@ impl SyntaxNodeVisitor for PositionFilter { } fn visit_switch_stmt_default(&mut self, n: &SwitchConditionalDefaultLabelNode, _: &TraversalContextStack) -> SwitchConditionalDefaultLabelTraversalPolicy { + let mut tp = SwitchConditionalDefaultLabelTraversalPolicy::default_to(false); + self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { - self.payload.borrow_mut().done = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } - TraversalPolicy::default_to(false) + tp } fn visit_break_stmt(&mut self, n: &BreakStatementNode, _: &TraversalContextStack) -> BreakStatementTraversalPolicy { + let mut tp = BreakStatementTraversalPolicy::default_to(false); + self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { - self.payload.borrow_mut().done = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } - TraversalPolicy::default_to(false) + tp } fn visit_continue_stmt(&mut self, n: &ContinueStatementNode, _: &TraversalContextStack) -> ContinueStatementTraversalPolicy { + let mut tp = ContinueStatementTraversalPolicy::default_to(false); + self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { - self.payload.borrow_mut().done = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } - TraversalPolicy::default_to(false) + tp } fn visit_delete_stmt(&mut self, n: &DeleteStatementNode, _: &TraversalContextStack) -> DeleteStatementTraversalPolicy { @@ -547,7 +776,8 @@ impl SyntaxNodeVisitor for PositionFilter { tp.traverse_value = true; } else { - self.payload.borrow_mut().done = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -563,7 +793,8 @@ impl SyntaxNodeVisitor for PositionFilter { tp.traverse_value = true; } else { - self.payload.borrow_mut().done = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -579,7 +810,8 @@ impl SyntaxNodeVisitor for PositionFilter { tp.traverse_expr = true; } else { - self.payload.borrow_mut().done = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -589,7 +821,7 @@ impl SyntaxNodeVisitor for PositionFilter { fn visit_nop_stmt(&mut self, n: &NopNode, _: &TraversalContextStack) { self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { - self.payload.borrow_mut().done = true; + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::Current); } } @@ -605,7 +837,8 @@ impl SyntaxNodeVisitor for PositionFilter { tp.traverse_inner = true; } else { - self.payload.borrow_mut().done = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -623,8 +856,11 @@ impl SyntaxNodeVisitor for PositionFilter { else if n.right().spans_position(self.pos) { tp.traverse_right = true; } + else if n.op().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::AssignmentOperationExpressionOp); + } else { - self.payload.borrow_mut().done = true; + tp.traverse_errors = true; } } @@ -642,8 +878,11 @@ impl SyntaxNodeVisitor for PositionFilter { else if n.right().spans_position(self.pos) { tp.traverse_right = true; } + else if n.op().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::BinaryOperationExpressionOp); + } else { - self.payload.borrow_mut().done = true; + tp.traverse_errors = true; } } @@ -658,8 +897,11 @@ impl SyntaxNodeVisitor for PositionFilter { if n.right().spans_position(self.pos) { tp.traverse_right = true; } + else if n.op().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::UnaryOperationExpressionOp); + } else { - self.payload.borrow_mut().done = true; + tp.traverse_errors = true; } } @@ -674,8 +916,12 @@ impl SyntaxNodeVisitor for PositionFilter { if n.lifetime_obj().map(|lifetime_obj| lifetime_obj.spans_position(self.pos)).unwrap_or(false) { tp.traverse_lifetime_obj = true; } - else { - self.payload.borrow_mut().done = true; + else if n.class().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::NewExpressionClass); + } + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -690,8 +936,12 @@ impl SyntaxNodeVisitor for PositionFilter { if n.value().spans_position(self.pos) { tp.traverse_value = true; } + else if n.target_type().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::TypeCastExpressionTargetType); + } else { - self.payload.borrow_mut().done = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -713,7 +963,8 @@ impl SyntaxNodeVisitor for PositionFilter { tp.traverse_alt = true; } else { - self.payload.borrow_mut().done = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -728,8 +979,11 @@ impl SyntaxNodeVisitor for PositionFilter { if n.accessor().spans_position(self.pos) { tp.traverse_accessor = true; } - else { - self.payload.borrow_mut().done = true; + else if n.member().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::MemberAccessExpressionMember); + } + else { + tp.traverse_errors = true; } } @@ -748,7 +1002,8 @@ impl SyntaxNodeVisitor for PositionFilter { tp.traverse_index = true; } else { - self.payload.borrow_mut().done = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -767,7 +1022,8 @@ impl SyntaxNodeVisitor for PositionFilter { tp.traverse_args = true; } else { - self.payload.borrow_mut().done = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -784,7 +1040,7 @@ impl SyntaxNodeVisitor for PositionFilter { tp.traverse_expr = true; } FunctionCallArgument::Omitted(_) => { - self.payload.borrow_mut().done = true; + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::Current); } } } @@ -795,42 +1051,42 @@ impl SyntaxNodeVisitor for PositionFilter { fn visit_identifier_expr(&mut self, n: &IdentifierNode, _: &TraversalContextStack) { self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { - self.payload.borrow_mut().done = true; + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::MemberAccessExpressionMember); } } fn visit_literal_expr(&mut self, n: &LiteralNode, _: &TraversalContextStack) { self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { - self.payload.borrow_mut().done = true; + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::MemberAccessExpressionMember); } } fn visit_this_expr(&mut self, n: &ThisExpressionNode, _: &TraversalContextStack) { self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { - self.payload.borrow_mut().done = true; + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::MemberAccessExpressionMember); } } fn visit_super_expr(&mut self, n: &SuperExpressionNode, _: &TraversalContextStack) { self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { - self.payload.borrow_mut().done = true; + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::MemberAccessExpressionMember); } } fn visit_parent_expr(&mut self, n: &ParentExpressionNode, _: &TraversalContextStack) { self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { - self.payload.borrow_mut().done = true; + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::MemberAccessExpressionMember); } } fn visit_virtual_parent_expr(&mut self, n: &VirtualParentExpressionNode, _: &TraversalContextStack) { self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { - self.payload.borrow_mut().done = true; + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::MemberAccessExpressionMember); } } @@ -840,6 +1096,8 @@ impl SyntaxNodeVisitor for PositionFilter { self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { tp.traverse_items = true; + tp.traverse_unnamed = true; + tp.traverse_errors = true; } tp @@ -852,10 +1110,15 @@ impl SyntaxNodeVisitor for PositionFilter { self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { - if n.type_arg().map(|type_arg| type_arg.spans_position(self.pos)).unwrap_or(false) { + if n.type_name().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::TypeAnnotationTypeName); + } + else if n.type_arg().map(|type_arg| type_arg.spans_position(self.pos)).unwrap_or(false) { tp.traverse_type_arg = true; - } else { - self.payload.borrow_mut().done = true; + } + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; } } @@ -863,12 +1126,47 @@ impl SyntaxNodeVisitor for PositionFilter { } fn visit_annotation(&mut self, n: &AnnotationNode, _: &TraversalContextStack) -> AnnotationTraversalPolicy { + let mut tp = AnnotationTraversalPolicy::default_to(false); + + self.currently_in_range = n.spans_position(self.pos); + if self.currently_in_range { + if n.name().spans_position(self.pos) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::AnnotationName); + } + else if n.arg().map(|arg| arg.spans_position(self.pos)).unwrap_or(false) { + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::AnnotationArg); + } + else { + tp.traverse_unnamed = true; + tp.traverse_errors = true; + } + } + + tp + } + + + fn visit_unnamed(&mut self, n: &UnnamedNode, _: &TraversalContextStack) { self.currently_in_range = n.spans_position(self.pos); if self.currently_in_range { - self.payload.borrow_mut().done = true; + self.payload.borrow_mut().leaf_endpoint = Some(PositionFilterEndpoint::Current); } + } + + + fn visit_error(&mut self, n: &witcherscript::ErrorNode, _: &TraversalContextStack) -> ErrorTraversalPolicy { + let mut tp = ErrorTraversalPolicy::default_to(false); - TraversalPolicy::default_to(false) + self.currently_in_range = n.spans_position(self.pos); + if self.currently_in_range { + tp.traverse = true; + } + + tp + } + + fn visit_error_child(&mut self, n: &AnyNode, _: &TraversalContextStack) { + self.currently_in_range = n.spans_position(self.pos); } } diff --git a/crates/lsp/src/providers/common/position_resolving.rs b/crates/lsp/src/providers/common/position_resolving.rs index 68b7749..9ccef6d 100644 --- a/crates/lsp/src/providers/common/position_resolving.rs +++ b/crates/lsp/src/providers/common/position_resolving.rs @@ -101,7 +101,6 @@ impl PositionTarget { /// A node visitor that can resolve a code identifier/symbol if a specified position points to such. /// Expects to work after PositionSeeker in visitor chain. pub struct TextDocumentPositionResolver<'a> { - pos: lsp::Position, doc: &'a ScriptDocument, pos_filter_payload: Rc>, symtab_marcher: SymbolTableMarcher<'a>, @@ -112,7 +111,6 @@ pub struct TextDocumentPositionResolver<'a> { impl<'a> TextDocumentPositionResolver<'a> { pub fn new_rc( - pos: lsp::Position, doc: &'a ScriptDocument, pos_filter_payload: Rc>, symtab_marcher: SymbolTableMarcher<'a>, @@ -120,7 +118,6 @@ impl<'a> TextDocumentPositionResolver<'a> { unl_builder_payload: Rc> ) -> Rc> { Rc::new(RefCell::new(Self { - pos, doc, pos_filter_payload, symtab_marcher, @@ -235,14 +232,16 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { fn visit_class_decl(&mut self, n: &ClassDeclarationNode) -> ClassDeclarationTraversalPolicy { - if self.pos_filter_payload.borrow().done { - let name = n.name(); - - if name.spans_position(self.pos) { - self.found_type_ident(&name); - } - else if let Some(base) = n.base().filter(|base| base.spans_position(self.pos)) { - self.found_type_ident(&base); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::ClassName => { + self.found_type_ident(&n.name()); + }, + PositionFilterEndpoint::ClassBase => { + self.found_type_ident(&n.base().unwrap()); + }, + _ => {} } } @@ -250,18 +249,19 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { } fn visit_state_decl(&mut self, n: &StateDeclarationNode) -> StateDeclarationTraversalPolicy { - if self.pos_filter_payload.borrow().done { - let name = n.name(); - let parent = n.parent(); - - if name.spans_position(self.pos) { - self.found_state_ident(&name); - } - else if parent.spans_position(self.pos) { - self.found_type_ident(&parent); - } - else if let Some(base) = n.base().filter(|base| base.spans_position(self.pos)) { - self.found_state_base_ident(&base); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::StateName => { + self.found_state_ident(&n.name()); + }, + PositionFilterEndpoint::StateParent => { + self.found_type_ident(&n.parent()); + }, + PositionFilterEndpoint::StateBase => { + self.found_state_base_ident(&n.base().unwrap()); + }, + _ => {} } } @@ -269,11 +269,13 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { } fn visit_struct_decl(&mut self, n: &StructDeclarationNode) -> StructDeclarationTraversalPolicy { - if self.pos_filter_payload.borrow().done { - let name = n.name(); - - if name.spans_position(self.pos) { - self.found_type_ident(&name); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::StructName => { + self.found_type_ident(&n.name()); + }, + _ => {} } } @@ -281,11 +283,13 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { } fn visit_enum_decl(&mut self, n: &EnumDeclarationNode) -> EnumDeclarationTraversalPolicy { - if self.pos_filter_payload.borrow().done { - let name = n.name(); - - if name.spans_position(self.pos) { - self.found_type_ident(&name); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::EnumName => { + self.found_type_ident(&n.name()); + }, + _ => {} } } @@ -294,11 +298,13 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { fn visit_enum_variant_decl(&mut self, n: &EnumVariantDeclarationNode) -> EnumVariantDeclarationTraversalPolicy { - if self.pos_filter_payload.borrow().done { - let name = n.name(); - - if name.spans_position(self.pos) { - self.found_data_decl_ident(&name); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::EnumVariantName => { + self.found_data_decl_ident(&n.name()); + }, + _ => {} } } @@ -306,18 +312,26 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { } fn visit_global_var_decl(&mut self, n: &MemberVarDeclarationNode) -> MemberVarDeclarationTraversalPolicy { - if let Some(name) = n.names().find(|name| name.spans_position(self.pos)) { - let class_path = n.annotation() - .and_then(|annot| annot.arg()) - .map(|arg| arg.value(self.doc)) - .map(|class_name| SymbolPathBuf::new(&class_name, SymbolCategory::Type)) - .unwrap_or_default(); - - self.found_target = Some(PositionTarget { - range: n.range(), - kind: PositionTargetKind::DataDeclarationNameIdentifier(name.value(self.doc).to_string()), - sympath_ctx: class_path, - }); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::VarName { nth } => { + let name = n.names().nth(nth).map(|n| n.value(self.doc).to_string()).unwrap_or_default(); + + let class_path = n.annotation() + .and_then(|annot| annot.arg()) + .map(|arg| arg.value(self.doc)) + .map(|class_name| SymbolPathBuf::new(&class_name, SymbolCategory::Type)) + .unwrap_or_default(); + + self.found_target = Some(PositionTarget { + range: n.range(), + kind: PositionTargetKind::DataDeclarationNameIdentifier(name), + sympath_ctx: class_path, + }); + }, + _ => {} + } } TraversalPolicy::default_to(true) @@ -325,29 +339,42 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, _: &TraversalContextStack) -> MemberVarDeclarationTraversalPolicy { // not checking the annotation, because it'll be erroneous anyways - if let Some(name) = n.names().find(|name| name.spans_position(self.pos)) { - self.found_data_decl_ident(&name); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::VarName { nth } => { + self.found_data_decl_ident(&n.names().nth(nth).unwrap()); + }, + _ => {} + } } TraversalPolicy::default_to(true) } fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, _: &TraversalContextStack) -> AutobindDeclarationTraversalPolicy { - let name = n.name(); - - if name.spans_position(self.pos) { - self.found_data_decl_ident(&name); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::AutobindName => { + self.found_data_decl_ident(&n.name()); + }, + _ => {} + } } TraversalPolicy::default_to(true) } fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode, ctx: &TraversalContextStack) -> MemberDefaultValueTraversalPolicy { - if self.pos_filter_payload.borrow().done { - let member = n.member(); - - if member.spans_position(self.pos) { - self.found_expression_ident(&member, member.clone().into(), ctx.top()); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::MemberDefaultValueMember => { + let member = n.member(); + self.found_expression_ident(&member, member.clone().into(), ctx.top()); + }, + _ => {} } } @@ -355,11 +382,14 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { } fn visit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode, ctx: &TraversalContextStack) -> MemberDefaultValueTraversalPolicy { - if self.pos_filter_payload.borrow().done { - let member = n.member(); - - if member.spans_position(self.pos) { - self.found_expression_ident(&member, member.clone().into(), ctx.top()); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::MemberDefaultValueMember => { + let member = n.member(); + self.found_expression_ident(&member, member.clone().into(), ctx.top()); + }, + _ => {} } } @@ -367,10 +397,15 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { } fn visit_member_hint(&mut self, n: &MemberHintNode, ctx: &TraversalContextStack) -> MemberHintTraversalPolicy { - let member = n.member(); - - if member.spans_position(self.pos) { - self.found_expression_ident(&member, member.clone().into(), ctx.top()); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::MemberHintMember => { + let member = n.member(); + self.found_expression_ident(&member, member.clone().into(), ctx.top()); + }, + _ => {} + } } TraversalPolicy::default_to(true) @@ -378,11 +413,13 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { fn visit_global_func_decl(&mut self, n: &FunctionDeclarationNode) -> FunctionDeclarationTraversalPolicy { - if self.pos_filter_payload.borrow().done { - let name = n.name(); - - if name.spans_position(self.pos) { - self.found_callable_decl_ident(&name); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::FunctionName => { + self.found_callable_decl_ident(&n.name()); + }, + _ => {} } } @@ -390,12 +427,14 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { } fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, _: &TraversalContextStack) -> FunctionDeclarationTraversalPolicy { - if self.pos_filter_payload.borrow().done { - let name = n.name(); - - // not checking the annotation, because it'll be erroneous anyways - if name.spans_position(self.pos) { - self.found_callable_decl_ident(&name); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::FunctionName => { + // not checking the annotation, because it'll be erroneous anyways + self.found_callable_decl_ident(&n.name()); + }, + _ => {} } } @@ -403,11 +442,13 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { } fn visit_event_decl(&mut self, n: &EventDeclarationNode, _: &TraversalContextStack) -> EventDeclarationTraversalPolicy { - if self.pos_filter_payload.borrow().done { - let name = n.name(); - - if name.spans_position(self.pos) { - self.found_callable_decl_ident(&name); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::EventName => { + self.found_callable_decl_ident(&n.name()); + }, + _ => {} } } @@ -415,8 +456,14 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { } fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, _: &TraversalContextStack) -> FunctionParameterGroupTraversalPolicy { - if let Some(name) = n.names().find(|name| name.spans_position(self.pos)) { - self.found_data_decl_ident(&name); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::FunctionParameterName { nth } => { + self.found_data_decl_ident(&n.names().nth(nth).unwrap()); + }, + _ => {} + } } TraversalPolicy::default_to(true) @@ -424,9 +471,13 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, _: &TraversalContextStack) -> VarDeclarationTraversalPolicy { - if self.pos_filter_payload.borrow().done { - if let Some(name) = n.names().find(|name| name.spans_position(self.pos)) { - self.found_data_decl_ident(&name); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::VarName { nth } => { + self.found_data_decl_ident(&n.names().nth(nth).unwrap()); + }, + _ => {} } } @@ -455,11 +506,13 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { } fn visit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, ctx: &TraversalContextStack) -> MemberFieldExpressionTraversalPolicy { - if self.pos_filter_payload.borrow().done { - let member = n.member(); - - if member.spans_position(self.pos) { - self.found_expression_ident(&member, n.clone().into(), ctx.top()); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::MemberAccessExpressionMember => { + self.found_expression_ident(&n.member(), n.clone().into(), ctx.top()); + }, + _ => {} } } @@ -467,11 +520,13 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { } fn visit_new_expr(&mut self, n: &NewExpressionNode, _: &TraversalContextStack) -> NewExpressionTraversalPolicy { - if self.pos_filter_payload.borrow().done { - let class = n.class(); - - if class.spans_position(self.pos) { - self.found_type_ident(&class); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::NewExpressionClass => { + self.found_type_ident(&n.class()); + }, + _ => {} } } @@ -479,11 +534,13 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { } fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, _: &TraversalContextStack) -> TypeCastExpressionTraversalPolicy { - if self.pos_filter_payload.borrow().done { - let target_type = n.target_type(); - - if n.target_type().spans_position(self.pos) { - self.found_type_ident(&target_type); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::TypeCastExpressionTargetType => { + self.found_type_ident(&n.target_type()); + }, + _ => {} } } @@ -492,17 +549,28 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> { fn visit_type_annotation(&mut self, n: &TypeAnnotationNode, _: &TraversalContextStack) -> TypeAnnotationTraversalPolicy { - let type_name = n.type_name(); - if type_name.spans_position(self.pos) { - self.found_type_ident(&type_name); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::TypeAnnotationTypeName => { + self.found_type_ident(&n.type_name()); + }, + _ => {} + } } TraversalPolicy::default_to(true) } fn visit_annotation(&mut self, n: &AnnotationNode, _: &TraversalContextStack) -> AnnotationTraversalPolicy { - if let Some(arg) = n.arg().filter(|arg| arg.spans_position(self.pos)) { - self.found_type_ident(&arg); + let endpoint = self.pos_filter_payload.borrow().leaf_endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + PositionFilterEndpoint::AnnotationArg => { + self.found_type_ident(&n.arg().unwrap()); + }, + _ => {} + } } TraversalPolicy::default_to(true) @@ -528,7 +596,6 @@ pub fn resolve_text_document_position<'a>(position: lsp::Position, script_state: let (sympath_builder, sympath_builder_payload) = SymbolPathBuilder::new(&script_state.buffer); let (unl_builder, unl_payload) = UnqualifiedNameLookupBuilder::new(&script_state.buffer, sympath_builder_payload.clone(), symtab_marcher.clone()); let resolver = TextDocumentPositionResolver::new_rc( - position, &script_state.buffer, detail_pos_filter_payload.clone(), symtab_marcher, diff --git a/crates/lsp/src/providers/selection_range.rs b/crates/lsp/src/providers/selection_range.rs index 15968c4..c17f936 100644 --- a/crates/lsp/src/providers/selection_range.rs +++ b/crates/lsp/src/providers/selection_range.rs @@ -3,7 +3,7 @@ use tower_lsp::lsp_types as lsp; use tower_lsp::jsonrpc::Result; use abs_path::AbsPath; use witcherscript::{ast::*, tokens::*, ErrorNode}; -use witcherscript_analysis::utils::{PositionFilter, PositionFilterPayload}; +use witcherscript_analysis::utils::{PositionFilter, PositionFilterEndpoint, PositionFilterPayload}; use crate::Backend; @@ -99,15 +99,18 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_class_decl(&mut self, n: &ClassDeclarationNode) -> ClassDeclarationTraversalPolicy { self.range_stack.push(n.range()); - if self.payload.borrow().done { - if n.name().spans_position(self.pos) { - self.range_stack.push(n.name().range()); - } - else if let Some(base) = n.base().filter(|base| base.spans_position(self.pos)) { - self.range_stack.push(base.range()); - } - else if let Some(spec) = n.specifiers().find(|spec| spec.spans_position(self.pos)) { - self.range_stack.push(spec.range()); + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::ClassName => { + self.range_stack.push(n.name().range()); + }, + PositionFilterEndpoint::ClassBase => { + self.range_stack.push(n.base().map(|b| b.range()).unwrap_or_default()); + }, + PositionFilterEndpoint::ClassSpecifier { nth } => { + self.range_stack.push(n.specifiers().nth(nth).map(|s| s.range()).unwrap_or_default()); + }, + _ => {} } } else if n.definition().spans_position(self.pos) { @@ -120,18 +123,21 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_state_decl(&mut self, n: &StateDeclarationNode) -> StateDeclarationTraversalPolicy { self.range_stack.push(n.range()); - if self.payload.borrow().done { - if n.name().spans_position(self.pos) { - self.range_stack.push(n.name().range()); - } - else if n.parent().spans_position(self.pos) { - self.range_stack.push(n.parent().range()); - } - else if let Some(base) = n.base().filter(|base| base.spans_position(self.pos)) { - self.range_stack.push(base.range()); - } - else if let Some(spec) = n.specifiers().find(|spec| spec.spans_position(self.pos)) { - self.range_stack.push(spec.range()); + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::StateName => { + self.range_stack.push(n.name().range()); + }, + PositionFilterEndpoint::StateParent => { + self.range_stack.push(n.parent().range()); + }, + PositionFilterEndpoint::StateBase => { + self.range_stack.push(n.base().map(|b| b.range()).unwrap_or_default()); + }, + PositionFilterEndpoint::StateSpecifier { nth } => { + self.range_stack.push(n.specifiers().nth(nth).map(|s| s.range()).unwrap_or_default()); + }, + _ => {} } } else if n.definition().spans_position(self.pos) { @@ -144,12 +150,15 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_struct_decl(&mut self, n: &StructDeclarationNode) -> StructDeclarationTraversalPolicy { self.range_stack.push(n.range()); - if self.payload.borrow().done { - if n.name().spans_position(self.pos) { - self.range_stack.push(n.name().range()); - } - else if let Some(spec) = n.specifiers().find(|spec| spec.spans_position(self.pos)) { - self.range_stack.push(spec.range()); + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::StructName => { + self.range_stack.push(n.name().range()); + }, + PositionFilterEndpoint::StructSpecifier { nth } => { + self.range_stack.push(n.specifiers().nth(nth).map(|s| s.range()).unwrap_or_default()); + }, + _ => {} } } else if n.definition().spans_position(self.pos) { @@ -162,9 +171,12 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_enum_decl(&mut self, n: &EnumDeclarationNode) -> EnumDeclarationTraversalPolicy { self.range_stack.push(n.range()); - if self.payload.borrow().done { - if n.name().spans_position(self.pos) { - self.range_stack.push(n.name().range()); + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::EnumName => { + self.range_stack.push(n.name().range()); + }, + _ => {} } } else if n.definition().spans_position(self.pos) { @@ -177,21 +189,23 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_enum_variant_decl(&mut self, n: &EnumVariantDeclarationNode) -> EnumVariantDeclarationTraversalPolicy { self.range_stack.push(n.range()); - if n.name().spans_position(self.pos) { - self.range_stack.push(n.name().range()); - } - if let Some(value) = n.value() { - match value { - EnumVariantValue::Int(int) => { - if int.spans_position(self.pos) { - self.range_stack.push(int.range()); - } + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::EnumVariantName => { + self.range_stack.push(n.name().range()); }, - EnumVariantValue::Hex(hex) => { - if hex.spans_position(self.pos) { - self.range_stack.push(hex.range()); + PositionFilterEndpoint::EnumVariantValue => { + match n.value() { + Some(EnumVariantValue::Int(int)) => { + self.range_stack.push(int.range()); + }, + Some(EnumVariantValue::Hex(hex)) => { + self.range_stack.push(hex.range()); + }, + _ => {} } - } + }, + _ => {} } } @@ -201,15 +215,18 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_global_func_decl(&mut self, n: &FunctionDeclarationNode) -> FunctionDeclarationTraversalPolicy { self.range_stack.push(n.range()); - if self.payload.borrow().done { - if n.name().spans_position(self.pos) { - self.range_stack.push(n.name().range()); - } - else if let Some(flavour) = n.flavour().filter(|f| f.spans_position(self.pos)) { - self.range_stack.push(flavour.range()); - } - else if let Some(spec) = n.specifiers().find(|spec| spec.spans_position(self.pos)) { - self.range_stack.push(spec.range()); + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::FunctionSpecifier { nth } => { + self.range_stack.push(n.specifiers().nth(nth).map(|s| s.range()).unwrap_or_default()); + }, + PositionFilterEndpoint::FunctionFlavour => { + self.range_stack.push(n.flavour().map(|f| f.range()).unwrap_or_default()); + }, + PositionFilterEndpoint::FunctionName => { + self.range_stack.push(n.name().range()); + }, + _ => {} } } else if n.params().spans_position(self.pos) { @@ -225,11 +242,16 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_global_var_decl(&mut self, n: &MemberVarDeclarationNode) -> MemberVarDeclarationTraversalPolicy { self.range_stack.push(n.range()); - if let Some(name) = n.names().find(|name| name.spans_position(self.pos)) { - self.range_stack.push(name.range()); - } - else if let Some(spec) = n.specifiers().find(|spec| spec.spans_position(self.pos)) { - self.range_stack.push(spec.range()); + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::VarSpecifier { nth } => { + self.range_stack.push(n.specifiers().nth(nth).map(|s| s.range()).unwrap_or_default()); + }, + PositionFilterEndpoint::VarName { nth } => { + self.range_stack.push(n.names().nth(nth).map(|n| n.range()).unwrap_or_default()); + }, + _ => {} + } } TraversalPolicy::default_to(false) @@ -241,15 +263,18 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, _: &TraversalContextStack) -> FunctionDeclarationTraversalPolicy { self.range_stack.push(n.range()); - if self.payload.borrow().done { - if n.name().spans_position(self.pos) { - self.range_stack.push(n.name().range()); - } - else if let Some(flavour) = n.flavour().filter(|f| f.spans_position(self.pos)) { - self.range_stack.push(flavour.range()); - } - else if let Some(spec) = n.specifiers().find(|spec| spec.spans_position(self.pos)) { - self.range_stack.push(spec.range()); + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::FunctionSpecifier { nth } => { + self.range_stack.push(n.specifiers().nth(nth).map(|s| s.range()).unwrap_or_default()); + }, + PositionFilterEndpoint::FunctionFlavour => { + self.range_stack.push(n.flavour().map(|f| f.range()).unwrap_or_default()); + }, + PositionFilterEndpoint::FunctionName => { + self.range_stack.push(n.name().range()); + }, + _ => {} } } else if n.params().spans_position(self.pos) { @@ -265,9 +290,12 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_event_decl(&mut self, n: &EventDeclarationNode, _: &TraversalContextStack) -> EventDeclarationTraversalPolicy { self.range_stack.push(n.range()); - if self.payload.borrow().done { - if n.name().spans_position(self.pos) { - self.range_stack.push(n.name().range()); + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::EventName => { + self.range_stack.push(n.name().range()); + }, + _ => {} } } else if n.params().spans_position(self.pos) { @@ -283,11 +311,16 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, _: &TraversalContextStack) -> FunctionParameterGroupTraversalPolicy { self.range_stack.push(n.range()); - if let Some(name) = n.names().find(|name| name.spans_position(self.pos)) { - self.range_stack.push(name.range()); - } - else if let Some(spec) = n.specifiers().find(|spec| spec.spans_position(self.pos)) { - self.range_stack.push(spec.range()); + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::FunctionParameterName { nth } => { + self.range_stack.push(n.names().nth(nth).map(|n| n.range()).unwrap_or_default()); + }, + PositionFilterEndpoint::FunctionParameterSpecifier { nth } => { + self.range_stack.push(n.specifiers().nth(nth).map(|s| s.range()).unwrap_or_default()); + }, + _ => {} + } } TraversalPolicy::default_to(false) @@ -296,11 +329,16 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, _: &TraversalContextStack) -> MemberVarDeclarationTraversalPolicy { self.range_stack.push(n.range()); - if let Some(name) = n.names().find(|name| name.spans_position(self.pos)) { - self.range_stack.push(name.range()); - } - else if let Some(spec) = n.specifiers().find(|spec| spec.spans_position(self.pos)) { - self.range_stack.push(spec.range()); + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::VarSpecifier { nth } => { + self.range_stack.push(n.specifiers().nth(nth).map(|s| s.range()).unwrap_or_default()); + }, + PositionFilterEndpoint::VarName { nth } => { + self.range_stack.push(n.names().nth(nth).map(|n| n.range()).unwrap_or_default()); + }, + _ => {} + } } TraversalPolicy::default_to(false) @@ -336,9 +374,12 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode, _: &TraversalContextStack) -> MemberDefaultValueTraversalPolicy { self.range_stack.push(n.range()); - if self.payload.borrow().done { - if n.member().spans_position(self.pos) { - self.range_stack.push(n.member().range()); + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::MemberDefaultValueMember => { + self.range_stack.push(n.member().range()); + }, + _ => {} } } @@ -354,9 +395,12 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode, _: &TraversalContextStack) -> MemberDefaultValueTraversalPolicy { self.range_stack.push(n.range()); - if self.payload.borrow().done { - if n.member().spans_position(self.pos) { - self.range_stack.push(n.member().range()); + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::MemberDefaultValueMember => { + self.range_stack.push(n.member().range()); + }, + _ => {} } } @@ -366,11 +410,16 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_member_hint(&mut self, n: &MemberHintNode, _: &TraversalContextStack) -> MemberHintTraversalPolicy { self.range_stack.push(n.range()); - if n.member().spans_position(self.pos) { - self.range_stack.push(n.member().range()); - } - else if n.value().spans_position(self.pos) { - self.range_stack.push(n.value().range()); + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::MemberHintMember => { + self.range_stack.push(n.member().range()); + }, + PositionFilterEndpoint::MemberHintValue => { + self.range_stack.push(n.value().range()); + } + _ => {} + } } TraversalPolicy::default_to(false) @@ -382,9 +431,12 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, _: &TraversalContextStack) -> VarDeclarationTraversalPolicy { self.range_stack.push(n.range()); - if self.payload.borrow().done { - if let Some(name) = n.names().find(|name| name.spans_position(self.pos)) { - self.range_stack.push(name.range()); + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::VarName { nth } => { + self.range_stack.push(n.names().nth(nth).map(|n| n.range()).unwrap_or_default()); + }, + _ => {} } } @@ -513,9 +565,12 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, _: &TraversalContextStack) -> MemberFieldExpressionTraversalPolicy { self.range_stack.push(n.range()); - if self.payload.borrow().done { - if n.member().spans_position(self.pos) { - self.range_stack.push(n.member().range()); + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::MemberAccessExpressionMember => { + self.range_stack.push(n.member().range()); + }, + _ => {} } } @@ -525,9 +580,12 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_new_expr(&mut self, n: &NewExpressionNode, _: &TraversalContextStack) -> NewExpressionTraversalPolicy { self.range_stack.push(n.range()); - if self.payload.borrow().done { - if n.class().spans_position(self.pos) { - self.range_stack.push(n.class().range()); + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::NewExpressionClass => { + self.range_stack.push(n.class().range()); + }, + _ => {} } } @@ -537,9 +595,12 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, _: &TraversalContextStack) -> TypeCastExpressionTraversalPolicy { self.range_stack.push(n.range()); - if self.payload.borrow().done { - if n.target_type().spans_position(self.pos) { - self.range_stack.push(n.target_type().range()); + if let Some(endpoint) = self.payload.borrow().leaf_endpoint { + match endpoint { + PositionFilterEndpoint::TypeCastExpressionTargetType => { + self.range_stack.push(n.target_type().range()); + }, + _ => {} } }