Extract a module-level assignment (`X = 42` or `X: int = 42`).
(&self, node: &Node, source: &str, file_path: &str)
| 209 | |
| 210 | /// Extract a module-level assignment (`X = 42` or `X: int = 42`). |
| 211 | fn extract_assignment(&self, node: &Node, source: &str, file_path: &str) -> Option<Entity> { |
| 212 | // Get the left side of the assignment |
| 213 | let left = node.child_by_field_name("left")?; |
| 214 | |
| 215 | // Only extract simple name assignments, not tuple/attribute assignments |
| 216 | if left.kind() != "identifier" { |
| 217 | return None; |
| 218 | } |
| 219 | |
| 220 | let name = self.node_text(&left, source); |
| 221 | |
| 222 | // Skip private variables |
| 223 | if name.starts_with('_') && !name.starts_with("__") { |
| 224 | return None; |
| 225 | } |
| 226 | |
| 227 | // Skip common non-semantic assignments |
| 228 | if name == "logger" || name == "log" { |
| 229 | return None; |
| 230 | } |
| 231 | |
| 232 | let line = node.start_position().row as u32 + 1; |
| 233 | let end_line = node.end_position().row as u32 + 1; |
| 234 | |
| 235 | // Check if it's ALL_CAPS (constant-like) |
| 236 | let is_const = name.chars().all(|c| c.is_uppercase() || c == '_'); |
| 237 | let kind = if is_const { |
| 238 | EntityKind::Const |
| 239 | } else { |
| 240 | EntityKind::Variable |
| 241 | }; |
| 242 | |
| 243 | let exported = !name.starts_with('_'); |
| 244 | let sig = self.node_text(node, source); |
| 245 | |
| 246 | let mut entity = Entity::new(name, kind, file_path, line, end_line); |
| 247 | entity = entity.with_signature(sig); |
| 248 | if exported { |
| 249 | entity.exported = true; |
| 250 | } |
| 251 | |
| 252 | Some(entity) |
| 253 | } |
| 254 | |
| 255 | /// Extract an import statement. |
| 256 | fn extract_import(&self, node: &Node, source: &str, file_path: &str) -> Option<Entity> { |
no test coverage detected