Extract a variable declaration (`local name = value`). Handles: - `local x = require("mod")` → Use node - `local CONST = ` → Const node (uppercase names)
(state: &mut ExtractionState, node: TsNode<'_>)
| 271 | /// - `local x = require("mod")` → Use node |
| 272 | /// - `local CONST = <literal>` → Const node (uppercase names) |
| 273 | fn visit_variable_declaration(state: &mut ExtractionState, node: TsNode<'_>) { |
| 274 | // variable_declaration contains an assignment_statement child. |
| 275 | let Some(assignment) = find_direct_child_by_kind(node, "assignment_statement") else { |
| 276 | return; |
| 277 | }; |
| 278 | |
| 279 | // Get the variable name from the variable_list. |
| 280 | let var_list = assignment |
| 281 | .child_by_field_name("variable_list") |
| 282 | .or_else(|| find_direct_child_by_kind(assignment, "variable_list")); |
| 283 | let name_node = var_list.and_then(|vl| { |
| 284 | // The first named child of variable_list should be the identifier. |
| 285 | find_direct_child_by_kind(vl, "identifier") |
| 286 | }); |
| 287 | let Some(n) = name_node else { |
| 288 | return; |
| 289 | }; |
| 290 | let name = state.node_text(n); |
| 291 | |
| 292 | // Get the value from the expression_list. |
| 293 | let expr_list = assignment |
| 294 | .child_by_field_name("expression_list") |
| 295 | .or_else(|| find_direct_child_by_kind(assignment, "expression_list")); |
| 296 | let value_node = expr_list.and_then(|el| el.named_child(0)); |
| 297 | |
| 298 | let Some(value_node) = value_node else { |
| 299 | return; |
| 300 | }; |
| 301 | |
| 302 | // Check if this is a require call → Use node. |
| 303 | if value_node.kind() == "function_call" { |
| 304 | let call_name = value_node |
| 305 | .child_by_field_name("name") |
| 306 | .map(|n| state.node_text(n)); |
| 307 | if call_name.as_deref() == Some("require") { |
| 308 | // Extract the module name from the arguments. |
| 309 | let mod_name = |
| 310 | Self::extract_require_module(state, value_node).unwrap_or(name.clone()); |
| 311 | Self::emit_use_node(state, node, &mod_name); |
| 312 | return; |
| 313 | } |
| 314 | } |
| 315 | |
| 316 | // Check if the value is a table constructor → skip (table declaration, not a const). |
| 317 | if value_node.kind() == "table_constructor" { |
| 318 | return; |
| 319 | } |
| 320 | |
| 321 | // Treat as Const node (Lua convention: uppercase names are constants, |
| 322 | // but we emit all local variable declarations with literal values as Const). |
| 323 | let is_literal = matches!( |
| 324 | value_node.kind(), |
| 325 | "number" | "string" | "true" | "false" | "nil" |
| 326 | ); |
| 327 | if !is_literal { |
| 328 | return; |
| 329 | } |
| 330 |
nothing calls this directly
no test coverage detected