(&mut self, root: Node<'t>)
| 1073 | // --- value refs ------------------------------------------------------------------- |
| 1074 | |
| 1075 | fn flush_value_refs(&mut self, root: Node<'t>) { |
| 1076 | let scopes = std::mem::take(&mut self.value_scopes); |
| 1077 | let mut targets = std::mem::take(&mut self.fs_values); |
| 1078 | let counts = std::mem::take(&mut self.fs_value_counts); |
| 1079 | if std::env::var("CODEGRAPH_VALUE_REFS").as_deref() == Ok("0") { |
| 1080 | return; |
| 1081 | } |
| 1082 | if targets.is_empty() || scopes.is_empty() || util::is_generated_file(self.file_path) { |
| 1083 | return; |
| 1084 | } |
| 1085 | |
| 1086 | // Shadow prune — Go declarator shapes: const_spec/var_spec (name = |
| 1087 | // first child) and short_var_declaration (left / expression_list). |
| 1088 | let mut decl_counts: HashMap<&str, u32> = HashMap::new(); |
| 1089 | let mut bump = |decl_counts: &mut HashMap<&'t str, u32>, name_node: Option<Node<'t>>, src: &'t str, targets: &HashMap<String, u32>| { |
| 1090 | if let Some(n) = name_node { |
| 1091 | if matches!(n.kind(), "identifier" | "simple_identifier") { |
| 1092 | let nm = &src[n.byte_range()]; |
| 1093 | if targets.contains_key(nm) { |
| 1094 | *decl_counts.entry(nm).or_insert(0) += 1; |
| 1095 | } |
| 1096 | } |
| 1097 | } |
| 1098 | }; |
| 1099 | let mut dstack: Vec<Node> = vec![root]; |
| 1100 | let mut dvisited = 0usize; |
| 1101 | while let Some(n) = dstack.pop() { |
| 1102 | if dvisited >= MAX_VALUE_REF_NODES { |
| 1103 | break; |
| 1104 | } |
| 1105 | dvisited += 1; |
| 1106 | match n.kind() { |
| 1107 | "const_spec" | "var_spec" => bump(&mut decl_counts, n.named_child(0), self.src, &targets), |
| 1108 | "short_var_declaration" => { |
| 1109 | let left = n |
| 1110 | .child_by_field_name("left") |
| 1111 | .or_else(|| n.child_by_field_name("pattern")) |
| 1112 | .or_else(|| n.named_child(0)); |
| 1113 | if let Some(left) = left { |
| 1114 | if left.kind() == "identifier" { |
| 1115 | bump(&mut decl_counts, Some(left), self.src, &targets); |
| 1116 | } else { |
| 1117 | for i in 0..left.named_child_count() { |
| 1118 | bump(&mut decl_counts, left.named_child(i), self.src, &targets); |
| 1119 | } |
| 1120 | } |
| 1121 | } |
| 1122 | } |
| 1123 | _ => {} |
| 1124 | } |
| 1125 | for i in 0..n.named_child_count() { |
| 1126 | if let Some(c) = n.named_child(i) { |
| 1127 | dstack.push(c); |
| 1128 | } |
| 1129 | } |
| 1130 | } |
| 1131 | let shadowed: Vec<String> = decl_counts |
| 1132 | .iter() |
no test coverage detected