diff --git a/rust/rubydex/src/indexing/ruby_indexer.rs b/rust/rubydex/src/indexing/ruby_indexer.rs index ddd3c6f1..c2796e76 100644 --- a/rust/rubydex/src/indexing/ruby_indexer.rs +++ b/rust/rubydex/src/indexing/ruby_indexer.rs @@ -1194,9 +1194,9 @@ impl<'a> RubyIndexer<'a> { fn handle_constant_visibility(&mut self, node: &ruby_prism::CallNode, visibility: Visibility) { let receiver = node.receiver(); - let receiver_name_id = match receiver { + let receiver_name_id = match &receiver { Some(ruby_prism::Node::ConstantPathNode { .. } | ruby_prism::Node::ConstantReadNode { .. }) => { - self.index_constant_reference(&receiver.unwrap(), true) + self.index_constant_reference(receiver.as_ref().unwrap(), true) } Some(ruby_prism::Node::SelfNode { .. }) | None => match self.nesting_stack.last() { Some(Nesting::Method(_)) => { @@ -1204,21 +1204,23 @@ impl<'a> RubyIndexer<'a> { return; } None => { + let call_name = String::from_utf8_lossy(node.name().as_slice()); self.local_graph.add_diagnostic( Rule::InvalidPrivateConstant, Offset::from_prism_location(&node.location()), - "Private constant called at top level".to_string(), + format!("`{call_name}` called at top level"), ); self.visit_call_node_parts(node); return; } _ => None, }, - _ => { + Some(other) => { + let call_name = String::from_utf8_lossy(node.name().as_slice()); self.local_graph.add_diagnostic( Rule::InvalidPrivateConstant, - Offset::from_prism_location(&node.location()), - "Dynamic receiver for private constant".to_string(), + Offset::from_prism_location(&other.location()), + format!("Dynamic receiver for `{call_name}`"), ); self.visit_call_node_parts(node); return; @@ -1230,29 +1232,14 @@ impl<'a> RubyIndexer<'a> { }; for argument in &arguments.arguments() { - let (name, location) = match argument { - ruby_prism::Node::SymbolNode { .. } => { - let symbol = argument.as_symbol_node().unwrap(); - if let Some(value_loc) = symbol.value_loc() { - (Self::location_to_string(&value_loc), value_loc) - } else { - continue; - } - } - ruby_prism::Node::StringNode { .. } => { - let string = argument.as_string_node().unwrap(); - let name = String::from_utf8_lossy(string.unescaped()).to_string(); - (name, argument.location()) - } - _ => { - self.local_graph.add_diagnostic( - Rule::InvalidPrivateConstant, - Offset::from_prism_location(&argument.location()), - "Private constant called with non-symbol argument".to_string(), - ); - self.visit(&argument); - continue; - } + let Some((name, location)) = Self::extract_literal_name(&argument) else { + self.local_graph.add_diagnostic( + Rule::InvalidPrivateConstant, + Offset::from_prism_location(&argument.location()), + "Private constant called with non-symbol argument".to_string(), + ); + self.visit(&argument); + continue; }; let str_id = self.local_graph.intern_string(name); @@ -1414,6 +1401,22 @@ impl<'a> RubyIndexer<'a> { } } + fn extract_literal_name<'b>(arg: &ruby_prism::Node<'b>) -> Option<(String, ruby_prism::Location<'b>)> { + match arg { + ruby_prism::Node::SymbolNode { .. } => { + let symbol = arg.as_symbol_node().unwrap(); + let value_loc = symbol.value_loc()?; + Some((Self::location_to_string(&value_loc), value_loc)) + } + ruby_prism::Node::StringNode { .. } => { + let string = arg.as_string_node().unwrap(); + let name = String::from_utf8_lossy(string.unescaped()).to_string(); + Some((name, arg.location())) + } + _ => None, + } + } + fn is_attr_call(arg: &ruby_prism::Node) -> bool { arg.as_call_node().is_some_and(|call| { let receiver = call.receiver(); @@ -1473,18 +1476,8 @@ impl<'a> RubyIndexer<'a> { visibility: Visibility, flags: DefinitionFlags, ) { - let (name, location) = match arg { - ruby_prism::Node::SymbolNode { .. } => { - let symbol = arg.as_symbol_node().unwrap(); - let Some(value_loc) = symbol.value_loc() else { return }; - (Self::location_to_string(&value_loc), value_loc) - } - ruby_prism::Node::StringNode { .. } => { - let string = arg.as_string_node().unwrap(); - let name = String::from_utf8_lossy(string.unescaped()).to_string(); - (name, arg.location()) - } - _ => return, + let Some((name, location)) = Self::extract_literal_name(arg) else { + return; }; self.create_method_visibility_definition_from_name(&name, &location, visibility, flags); diff --git a/rust/rubydex/src/indexing/ruby_indexer_tests.rs b/rust/rubydex/src/indexing/ruby_indexer_tests.rs index 6f2ff2f6..e382cb60 100644 --- a/rust/rubydex/src/indexing/ruby_indexer_tests.rs +++ b/rust/rubydex/src/indexing/ruby_indexer_tests.rs @@ -1768,9 +1768,9 @@ mod visibility_tests { assert_local_diagnostics_eq!( &context, vec![ - "invalid-private-constant: Private constant called at top level (1:1-1:30)", - "invalid-private-constant: Private constant called at top level (2:1-2:35)", - "invalid-private-constant: Dynamic receiver for private constant (3:1-3:34)", + "invalid-private-constant: `private_constant` called at top level (1:1-1:30)", + "invalid-private-constant: `private_constant` called at top level (2:1-2:35)", + "invalid-private-constant: Dynamic receiver for `private_constant` (3:1-3:4)", "invalid-private-constant: Private constant called with non-symbol argument (6:20-6:31)", "invalid-private-constant: Private constant called with non-symbol argument (6:33-6:44)", ]