Skip to content

Commit 41c3253

Browse files
ind-igoclaude
andcommitted
Improve query coverage for Go, Rust, Java, C++, C, Solidity, Ruby, Lua, Bash, Zig
Expands tree-sitter symbol extraction across 10 languages with new patterns for structs/interfaces, fields, constants, constructors, namespaces, templates, and more. Highlights per validation repo: - Go (gin): +52% symbols, now distinguishes struct/interface/field/const - C++ (nlohmann/json): +62% symbols, adds namespaces, templates, aliases, concepts - Zig (zig compiler): +35% symbols, adds fields, consts, test declarations - Java (guava): +33% symbols, adds fields, constants, constructors, records - Solidity (OZ): +15% symbols, adds modifiers, state vars, errors, UDVTs - Rust (axum): +3%, adds const_item/static_item Dedup changes in extract.rs to support overlapping generic+specific patterns: - `definition.struct` and `definition.trait` added as default capture kinds - Same byte-range dedup now lets later (more specific) patterns win - Added containment-based dedup for same-name/same-kind symbols to eliminate C++ template_declaration wrapper duplicates - Strip surrounding quotes from string-literal names (Zig test names) Index version bumped 7→8. 15 new tests covering all new patterns. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent cbd98be commit 41c3253

14 files changed

Lines changed: 452 additions & 33 deletions

File tree

src/index.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
99

1010
use crate::language::{detect_language, parse_and_extract, primary_extension, LangError};
1111

12-
pub const INDEX_VERSION: u32 = 7;
12+
pub const INDEX_VERSION: u32 = 8;
1313

1414
/// Compute the cache path for a given project root.
1515
/// Returns `~/.cache/cx/indexes/<hash>.db` where hash is derived from the canonical path.

src/language/extract.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,14 @@ pub(super) fn extract_symbols(
107107
};
108108

109109
let name = match name_n.utf8_text(source) {
110-
Ok(s) => s.to_string(),
110+
Ok(s) => {
111+
// Strip surrounding quotes from string-literal names (e.g. Zig test names)
112+
if s.starts_with('"') && s.ends_with('"') && s.len() >= 2 {
113+
s[1..s.len()-1].to_string()
114+
} else {
115+
s.to_string()
116+
}
117+
}
111118
Err(_) => continue,
112119
};
113120

@@ -158,6 +165,8 @@ fn resolve_kind(config: &LanguageConfig, capture_name: &str, node: &Node) -> Opt
158165
"definition.enum" => Some(SymbolKind::Enum),
159166
"definition.module" => Some(SymbolKind::Module),
160167
"definition.constant" => Some(SymbolKind::Const),
168+
"definition.struct" => Some(SymbolKind::Struct),
169+
"definition.trait" => Some(SymbolKind::Trait),
161170
"definition.event" => Some(SymbolKind::Event),
162171
"definition.field" => Some(SymbolKind::Field),
163172
"definition.macro" => Some(SymbolKind::Fn),
@@ -226,15 +235,26 @@ fn deduplicate(symbols: Vec<Symbol>) -> Vec<Symbol> {
226235

227236
for sym in symbols {
228237
if let Some(&idx) = seen.get(&sym.byte_range) {
229-
if deduped[idx].kind == sym.kind {
230-
// Later pattern wins for same byte range + kind (more specific name capture)
231-
deduped[idx] = sym;
232-
}
238+
// Later pattern wins for same byte range (more specific capture)
239+
deduped[idx] = sym;
233240
} else {
234241
seen.insert(sym.byte_range, deduped.len());
235242
deduped.push(sym);
236243
}
237244
}
238245

239-
deduped
246+
// Remove symbols whose range is strictly contained within another symbol
247+
// of the same name (e.g. class_specifier inside template_declaration).
248+
let ranges: Vec<_> = deduped.iter().map(|s| (s.name.as_str(), s.byte_range)).collect();
249+
let mut keep = vec![true; deduped.len()];
250+
for (i, (name_i, (start_i, end_i))) in ranges.iter().enumerate() {
251+
for (j, (name_j, (start_j, end_j))) in ranges.iter().enumerate() {
252+
if i != j && name_i == name_j && deduped[i].kind == deduped[j].kind && start_j <= start_i && end_i <= end_j && (start_j, end_j) != (start_i, end_i) {
253+
keep[i] = false;
254+
break;
255+
}
256+
}
257+
}
258+
259+
deduped.into_iter().zip(keep).filter(|(_, k)| *k).map(|(s, _)| s).collect()
240260
}

src/language/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ static LANGUAGES: &[LanguageConfig] = &[
118118
sig_body_child: None,
119119
sig_delimiter: Some(b'{'),
120120
kind_overrides: &[],
121-
ref_node_types: &["identifier"],
121+
ref_node_types: &["identifier", "type_identifier"],
122122
},
123123
LanguageConfig {
124124
name: "ruby",

src/language/queries/bash.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
pub const QUERY: &str = r#"
2+
; --- Functions ---
3+
24
(function_definition
35
name: (word) @name) @definition.function
6+
7+
; --- Top-level variable assignments ---
8+
9+
(program
10+
(variable_assignment
11+
name: (variable_name) @name) @definition.constant)
412
"#;

src/language/queries/c.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
pub const QUERY: &str = r#"
2+
; --- Functions ---
3+
24
(function_definition
35
declarator: (function_declarator
46
declarator: (identifier) @name)) @definition.function
@@ -8,13 +10,34 @@ pub const QUERY: &str = r#"
810
declarator: (function_declarator
911
declarator: (identifier) @name))) @definition.function
1012
13+
; --- Structs & unions ---
14+
1115
(struct_specifier
1216
name: (type_identifier) @name
1317
body: (_)) @definition.class
1418
19+
(union_specifier
20+
name: (type_identifier) @name
21+
body: (_)) @definition.class
22+
23+
; --- Enums ---
24+
1525
(enum_specifier
1626
name: (type_identifier) @name) @definition.enum
1727
28+
; --- Type definitions ---
29+
1830
(type_definition
1931
declarator: (type_identifier) @name) @definition.type
32+
33+
; --- Function prototypes ---
34+
35+
(declaration
36+
declarator: (function_declarator
37+
declarator: (identifier) @name)) @definition.function
38+
39+
(declaration
40+
declarator: (pointer_declarator
41+
declarator: (function_declarator
42+
declarator: (identifier) @name))) @definition.function
2043
"#;

src/language/queries/cpp.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
pub const QUERY: &str = r#"
2+
; --- Functions (also covers in-class constructors) ---
3+
24
(function_definition
35
declarator: (function_declarator
46
declarator: (identifier) @name)) @definition.function
@@ -17,16 +19,70 @@ pub const QUERY: &str = r#"
1719
declarator: (qualified_identifier
1820
name: (identifier) @name))) @definition.method
1921
22+
; --- Destructors ---
23+
24+
(function_definition
25+
declarator: (function_declarator
26+
declarator: (destructor_name
27+
(identifier) @name))) @definition.function
28+
29+
(function_definition
30+
declarator: (function_declarator
31+
declarator: (qualified_identifier
32+
name: (destructor_name
33+
(identifier) @name)))) @definition.function
34+
35+
; --- Template functions ---
36+
37+
(template_declaration
38+
(function_definition
39+
declarator: (function_declarator
40+
declarator: (identifier) @name))) @definition.function
41+
42+
(template_declaration
43+
(function_definition
44+
declarator: (function_declarator
45+
declarator: (qualified_identifier
46+
name: (identifier) @name)))) @definition.method
47+
48+
; --- Classes & structs ---
49+
2050
(struct_specifier
2151
name: (type_identifier) @name
2252
body: (_)) @definition.class
2353
2454
(class_specifier
2555
name: (type_identifier) @name) @definition.class
2656
57+
(template_declaration
58+
(class_specifier
59+
name: (type_identifier) @name)) @definition.class
60+
61+
(template_declaration
62+
(struct_specifier
63+
name: (type_identifier) @name
64+
body: (_))) @definition.class
65+
66+
; --- Enums ---
67+
2768
(enum_specifier
2869
name: (type_identifier) @name) @definition.enum
2970
71+
; --- Type definitions & aliases ---
72+
3073
(type_definition
3174
declarator: (type_identifier) @name) @definition.type
75+
76+
(alias_declaration
77+
name: (type_identifier) @name) @definition.type
78+
79+
; --- Namespaces ---
80+
81+
(namespace_definition
82+
name: (namespace_identifier) @name) @definition.module
83+
84+
; --- Concepts (C++20) ---
85+
86+
(concept_definition
87+
name: (identifier) @name) @definition.type
3288
"#;

src/language/queries/go.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,44 @@
11
pub const QUERY: &str = r#"
2+
; --- Functions ---
3+
24
(function_declaration
35
name: (identifier) @name) @definition.function
46
57
(method_declaration
68
name: (field_identifier) @name) @definition.method
79
10+
; --- Structs (must come before generic type_spec) ---
11+
12+
(type_spec
13+
name: (type_identifier) @name
14+
type: (struct_type)) @definition.struct
15+
16+
; --- Interfaces ---
17+
18+
(type_spec
19+
name: (type_identifier) @name
20+
type: (interface_type)) @definition.interface
21+
22+
; --- Other named types (catch-all for type aliases, func types, etc.) ---
23+
824
(type_spec
925
name: (type_identifier) @name) @definition.type
26+
27+
(type_alias
28+
name: (type_identifier) @name) @definition.type
29+
30+
; --- Constants ---
31+
32+
(const_spec
33+
name: (identifier) @name) @definition.constant
34+
35+
; --- Interface method specs ---
36+
37+
(method_elem
38+
name: (field_identifier) @name) @definition.method
39+
40+
; --- Struct fields ---
41+
42+
(field_declaration
43+
name: (field_identifier) @name) @definition.field
1044
"#;

src/language/queries/java.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,39 @@
11
pub const QUERY: &str = r#"
2+
; --- Type declarations ---
3+
24
(class_declaration
35
name: (identifier) @name) @definition.class
46
5-
(method_declaration
6-
name: (identifier) @name) @definition.method
7+
(record_declaration
8+
name: (identifier) @name) @definition.class
79
810
(interface_declaration
911
name: (identifier) @name) @definition.interface
1012
13+
(annotation_type_declaration
14+
name: (identifier) @name) @definition.interface
15+
1116
(enum_declaration
1217
name: (identifier) @name) @definition.enum
18+
19+
; --- Methods & constructors ---
20+
21+
(method_declaration
22+
name: (identifier) @name) @definition.method
23+
24+
(constructor_declaration
25+
name: (identifier) @name) @definition.method
26+
27+
; --- Fields & constants ---
28+
29+
(field_declaration
30+
declarator: (variable_declarator
31+
name: (identifier) @name)) @definition.field
32+
33+
(constant_declaration
34+
declarator: (variable_declarator
35+
name: (identifier) @name)) @definition.constant
36+
37+
(enum_constant
38+
name: (identifier) @name) @definition.constant
1339
"#;

src/language/queries/lua.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
pub const QUERY: &str = r#"
2+
; --- Functions ---
3+
24
(function_declaration
35
name: (identifier) @name) @definition.function
46
@@ -9,4 +11,12 @@ pub const QUERY: &str = r#"
911
(function_declaration
1012
name: (method_index_expression
1113
method: (identifier) @name)) @definition.method
14+
15+
; --- Top-level local variables (module tables, constants) ---
16+
17+
(chunk
18+
(variable_declaration
19+
(assignment_statement
20+
(variable_list
21+
name: (identifier) @name))) @definition.constant)
1222
"#;

src/language/queries/ruby.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,29 @@
11
pub const QUERY: &str = r#"
2+
; --- Classes & modules ---
3+
4+
(class
5+
name: (constant) @name) @definition.class
6+
7+
(module
8+
name: (constant) @name) @definition.module
9+
10+
; --- Methods ---
11+
212
(method
313
name: (_) @name) @definition.method
414
515
(singleton_method
616
name: (_) @name) @definition.method
717
8-
(class
9-
name: (constant) @name) @definition.class
18+
(alias
19+
name: (_) @name) @definition.method
1020
11-
(module
12-
name: (constant) @name) @definition.module
21+
; --- Constants ---
22+
23+
(assignment
24+
left: (constant) @name) @definition.constant
25+
26+
(assignment
27+
left: (scope_resolution
28+
name: (constant) @name)) @definition.constant
1329
"#;

0 commit comments

Comments
 (0)