zeta2: Parse imports via Tree-sitter queries + improve zeta retrieval-stats (#39735)

Release Notes:

- N/A

---------

Co-authored-by: Max <max@zed.dev>
Co-authored-by: Agus <agus@zed.dev>
Co-authored-by: Oleksiy <oleksiy@zed.dev>
This commit is contained in:
Michael Sloan
2025-10-08 12:04:06 -06:00
committed by GitHub
co-authored by Max Agus Oleksiy
parent 5fd187769d
commit bcef3b5010
35 changed files with 3076 additions and 508 deletions
+72
View File
@@ -777,6 +777,15 @@ pub struct LanguageConfig {
/// A list of preferred debuggers for this language.
#[serde(default)]
pub debuggers: IndexSet<SharedString>,
/// A list of import namespace segments that aren't expected to appear in file paths. For
/// example, "super" and "crate" in Rust.
#[serde(default)]
pub ignored_import_segments: HashSet<Arc<str>>,
/// Regular expression that matches substrings to omit from import paths, to make the paths more
/// similar to how they are specified when imported. For example, "/mod\.rs$" or "/__init__\.py$".
#[serde(default, deserialize_with = "deserialize_regex")]
#[schemars(schema_with = "regex_json_schema")]
pub import_path_strip_regex: Option<Regex>,
}
#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
@@ -973,6 +982,8 @@ impl Default for LanguageConfig {
completion_query_characters: Default::default(),
linked_edit_characters: Default::default(),
debuggers: Default::default(),
ignored_import_segments: Default::default(),
import_path_strip_regex: None,
}
}
}
@@ -1162,6 +1173,7 @@ pub struct Grammar {
pub(crate) injection_config: Option<InjectionConfig>,
pub(crate) override_config: Option<OverrideConfig>,
pub(crate) debug_variables_config: Option<DebugVariablesConfig>,
pub(crate) imports_config: Option<ImportsConfig>,
pub(crate) highlight_map: Mutex<HighlightMap>,
}
@@ -1314,6 +1326,17 @@ pub struct DebugVariablesConfig {
pub objects_by_capture_ix: Vec<(u32, DebuggerTextObject)>,
}
pub struct ImportsConfig {
pub query: Query,
pub import_ix: u32,
pub name_ix: Option<u32>,
pub namespace_ix: Option<u32>,
pub source_ix: Option<u32>,
pub list_ix: Option<u32>,
pub wildcard_ix: Option<u32>,
pub alias_ix: Option<u32>,
}
impl Language {
pub fn new(config: LanguageConfig, ts_language: Option<tree_sitter::Language>) -> Self {
Self::new_with_id(LanguageId::new(), config, ts_language)
@@ -1346,6 +1369,7 @@ impl Language {
runnable_config: None,
error_query: Query::new(&ts_language, "(ERROR) @error").ok(),
debug_variables_config: None,
imports_config: None,
ts_language,
highlight_map: Default::default(),
})
@@ -1427,6 +1451,11 @@ impl Language {
.with_debug_variables_query(query.as_ref())
.context("Error loading debug variables query")?;
}
if let Some(query) = queries.imports {
self = self
.with_imports_query(query.as_ref())
.context("Error loading imports query")?;
}
Ok(self)
}
@@ -1595,6 +1624,45 @@ impl Language {
Ok(self)
}
pub fn with_imports_query(mut self, source: &str) -> Result<Self> {
let query = Query::new(&self.expect_grammar()?.ts_language, source)?;
let mut import_ix = 0;
let mut name_ix = None;
let mut namespace_ix = None;
let mut source_ix = None;
let mut list_ix = None;
let mut wildcard_ix = None;
let mut alias_ix = None;
if populate_capture_indices(
&query,
&self.config.name,
"imports",
&[],
&mut [
Capture::Required("import", &mut import_ix),
Capture::Optional("name", &mut name_ix),
Capture::Optional("namespace", &mut namespace_ix),
Capture::Optional("source", &mut source_ix),
Capture::Optional("list", &mut list_ix),
Capture::Optional("wildcard", &mut wildcard_ix),
Capture::Optional("alias", &mut alias_ix),
],
) {
self.grammar_mut()?.imports_config = Some(ImportsConfig {
query,
import_ix,
name_ix,
namespace_ix,
source_ix,
list_ix,
wildcard_ix,
alias_ix,
});
}
return Ok(self);
}
pub fn with_brackets_query(mut self, source: &str) -> Result<Self> {
let query = Query::new(&self.expect_grammar()?.ts_language, source)?;
let mut open_capture_ix = 0;
@@ -2149,6 +2217,10 @@ impl Grammar {
pub fn debug_variables_config(&self) -> Option<&DebugVariablesConfig> {
self.debug_variables_config.as_ref()
}
pub fn imports_config(&self) -> Option<&ImportsConfig> {
self.imports_config.as_ref()
}
}
impl CodeLabel {
+2
View File
@@ -229,6 +229,7 @@ pub const QUERY_FILENAME_PREFIXES: &[(
("runnables", |q| &mut q.runnables),
("debugger", |q| &mut q.debugger),
("textobjects", |q| &mut q.text_objects),
("imports", |q| &mut q.imports),
];
/// Tree-sitter language queries for a given language.
@@ -245,6 +246,7 @@ pub struct LanguageQueries {
pub runnables: Option<Cow<'static, str>>,
pub text_objects: Option<Cow<'static, str>>,
pub debugger: Option<Cow<'static, str>>,
pub imports: Option<Cow<'static, str>>,
}
#[derive(Clone, Default)]