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